auditor

An aarch64 constant-time memory access auditing tool.
git clone git://git.ppad.tech/auditor.git
Log | Files | Refs | README | LICENSE

commit f66e98a34416cbf8f5a8bc7c8193de5382b38bc7
parent 58c63e037805555270aeedcd49dcb19673287f05
Author: Jared Tobin <jared@jtobin.io>
Date:   Tue, 10 Feb 2026 14:07:49 +0400

fix: handle adds/subs and post-indexed stores for SP invalidation

- adds/subs now use updateWithSpCheck like add/sub
- Post-indexed stores ([sp], #imm) now clear the stack map

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Diffstat:
Mlib/Audit/AArch64/Taint.hs | 20++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/lib/Audit/AArch64/Taint.hs b/lib/Audit/AArch64/Taint.hs @@ -121,8 +121,8 @@ transfer instr st = case instr of -- Clear stack map if SP is modified (offsets become stale) Add dst r1 op -> updateWithSpCheck dst (join2 (getTaint r1 st) (operandTaint op st)) st Sub dst r1 op -> updateWithSpCheck dst (join2 (getTaint r1 st) (operandTaint op st)) st - Adds dst r1 op -> setTaint dst (join2 (getTaint r1 st) (operandTaint op st)) st - Subs dst r1 op -> setTaint dst (join2 (getTaint r1 st) (operandTaint op st)) st + Adds dst r1 op -> updateWithSpCheck dst (join2 (getTaint r1 st) (operandTaint op st)) st + Subs dst r1 op -> updateWithSpCheck dst (join2 (getTaint r1 st) (operandTaint op st)) st Adc dst r1 r2 -> setTaint dst (join2 (getTaint r1 st) (getTaint r2 st)) st Adcs dst r1 r2 -> setTaint dst (join2 (getTaint r1 st) (getTaint r2 st)) st Sbc dst r1 r2 -> setTaint dst (join2 (getTaint r1 st) (getTaint r2 st)) st @@ -250,18 +250,21 @@ updateWithSpCheck dst t st | otherwise = setTaint dst t st -- | Track a store to stack if address is [sp, #imm]. --- Pre-indexed addressing modifies SP, invalidating the stack map. +-- Pre/post-indexed addressing modifies SP, invalidating the stack map. storeToStack :: Reg -> AddrMode -> TaintState -> TaintState storeToStack src addr st = case addr of BaseImm SP imm -> setStackTaint (fromInteger imm) (getTaint src st) st PreIndex SP imm -> - -- Store first, then clear (SP changes after access) + -- Store at sp+imm, then SP changes clearStackMap (setStackTaint (fromInteger imm) (getTaint src st) st) + PostIndex SP _ -> + -- Store at sp, then SP changes (offset 0) + clearStackMap (setStackTaint 0 (getTaint src st) st) _ -> st -- Non-SP stores don't affect stack tracking -- | Track a store pair to stack if address is [sp, #imm]. -- Stores src1 at offset and src2 at offset+8. --- Pre-indexed addressing modifies SP, invalidating the stack map. +-- Pre/post-indexed addressing modifies SP, invalidating the stack map. storePairToStack :: Reg -> Reg -> AddrMode -> TaintState -> TaintState storePairToStack src1 src2 addr st = case addr of BaseImm SP imm -> @@ -269,11 +272,16 @@ storePairToStack src1 src2 addr st = case addr of in setStackTaint off (getTaint src1 st) (setStackTaint (off + 8) (getTaint src2 st) st) PreIndex SP imm -> - -- Store first, then clear (SP changes after access) + -- Store at sp+imm and sp+imm+8, then SP changes let off = fromInteger imm st' = setStackTaint off (getTaint src1 st) (setStackTaint (off + 8) (getTaint src2 st) st) in clearStackMap st' + PostIndex SP _ -> + -- Store at sp and sp+8, then SP changes + let st' = setStackTaint 0 (getTaint src1 st) + (setStackTaint 8 (getTaint src2 st) st) + in clearStackMap st' _ -> st -- | Load from memory, handling special cases: