auditor

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

commit 1bfe17d14e2dd2ecf12e2e937aab38a2b71c1bc0
parent 622a7ad267120de5326656b4aa68096d41d5c28d
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 14 Feb 2026 11:49:22 +0400

fix: replace lazy foldl with foldl' to avoid space leaks

Lazy foldl builds thunks when accumulating strict tuples with Maps.
Use foldl' from Data.List in CFG, NCT, and CallGraph modules.

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

Diffstat:
Mlib/Audit/AArch64/CFG.hs | 3++-
Mlib/Audit/AArch64/CallGraph.hs | 3++-
Mlib/Audit/AArch64/NCT.hs | 3++-
3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/lib/Audit/AArch64/CFG.hs b/lib/Audit/AArch64/CFG.hs @@ -32,6 +32,7 @@ module Audit.AArch64.CFG ( import Audit.AArch64.Types import Control.DeepSeq (NFData) +import Data.List (foldl') import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import Data.Primitive.Array (Array) @@ -127,7 +128,7 @@ hasFallthroughInstr (Just instr) = case instr of -- | Build function blocks map in a single pass over blocks. buildFuncBlocksOnce :: [BasicBlock] -> Map Text [Int] -buildFuncBlocksOnce bbs = finalize $ foldl step (Nothing, Map.empty) indexed +buildFuncBlocksOnce bbs = finalize $ foldl' step (Nothing, Map.empty) indexed where nBlocks = length bbs indexed = zip [0..] bbs diff --git a/lib/Audit/AArch64/CallGraph.hs b/lib/Audit/AArch64/CallGraph.hs @@ -24,6 +24,7 @@ module Audit.AArch64.CallGraph ( import Audit.AArch64.CFG (isFunctionLabel) import Audit.AArch64.Types (Instr(..), Line(..)) import Data.Graph (Graph, Vertex, graphFromEdges, reachable, transposeG) +import Data.List (foldl') import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map import Data.Set (Set) @@ -51,7 +52,7 @@ buildCallGraph lns = CallGraph graph nodeFromV vertexFromK allSyms -- Build map from symbol to its instructions. -- State: (current symbol, accumulated map) symInstrs :: Map Text [Instr] - symInstrs = snd $ foldl step ("<unknown>", Map.empty) lns + symInstrs = snd $ foldl' step ("<unknown>", Map.empty) lns where step (curSym, acc) ln = let -- Update current symbol when we see a function label diff --git a/lib/Audit/AArch64/NCT.hs b/lib/Audit/AArch64/NCT.hs @@ -29,6 +29,7 @@ import Audit.AArch64.CFG (isFunctionLabel) import Audit.AArch64.Types import Control.DeepSeq (NFData) import Data.IntMap.Strict (IntMap) +import Data.List (foldl') import qualified Data.IntMap.Strict as IntMap import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map @@ -53,7 +54,7 @@ data NctFinding = NctFinding -- | Scan parsed lines for non-constant-time instructions. -- Returns findings grouped by function symbol. scanNct :: [Line] -> Map Text [NctFinding] -scanNct = finalize . foldl step (unknownSym, Map.empty) +scanNct = finalize . foldl' step (unknownSym, Map.empty) where unknownSym = "<unknown>"