auditor

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

commit 622a7ad267120de5326656b4aa68096d41d5c28d
parent 85d6377d5d28913567bfb2226ab1c319717ca399
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri, 13 Feb 2026 20:09:57 +0400

fix: make --callers work with --scan-nct --symbol

Previously --callers only affected --list-symbols mode. Now it also
works with NCT scanning to analyze all symbols that can reach the
target rather than all symbols the target can reach.

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

Diffstat:
Mapp/Main.hs | 36++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/app/Main.hs b/app/Main.hs @@ -6,14 +6,14 @@ import Audit.AArch64 ( AuditResult(..), Violation(..), ViolationReason(..) , TaintConfig(..) , NctReason(..), NctFinding(..), nctLine, nctInstr, nctReason - , LineMap, isGhcRuntimeFinding - , SymbolScanResult(..) + , LineMap, buildLineMap, isGhcRuntimeFinding + , SymbolScanResult(..), scanNct , buildCallGraph, allSymbols, reachableSymbols, reachingSymbols , symbolExists , auditFile, auditFileInterProc , auditFileWithConfig, auditFileInterProcWithConfig , parseFile, regName, loadTaintConfig - , scanNctFile, scanNctFileForSymbol + , scanNctFile ) import Audit.AArch64.Parser (parseAsm) import Audit.AArch64.Types (Instr) @@ -144,7 +144,7 @@ main = do else if optScanNct opts then case optSymbol opts of Just sym -> do - result <- scanNctFileForSymbol sym (optInput opts) + result <- scanNctForSymbol opts sym case result of Left err -> do TIO.putStrLn $ "Error: " <> err @@ -264,6 +264,34 @@ listSymbols opts = do else TIO.putStrLn $ "\n" <> T.pack (show (length filtered)) <> " symbols" +-- | NCT scan for a symbol (callees or callers based on options). +scanNctForSymbol :: Options -> Text -> IO (Either Text SymbolScanResult) +scanNctForSymbol opts rootSym = do + bs <- BS.readFile (optInput opts) + case decodeUtf8' bs of + Left err -> pure (Left (T.pack (show err))) + Right src -> + case parseAsm src of + Left _ -> pure (Left "parse failed") + Right lns -> do + let cg = buildCallGraph lns + if not (symbolExists rootSym cg) + then pure (Left ("symbol not found: " <> rootSym)) + else do + let syms = if optCallers opts + then reachingSymbols rootSym cg + else reachableSymbols rootSym cg + lineMap = buildLineMap lns + allFindings = scanNct lns + filtered = Map.filterWithKey + (\sym _ -> Set.member sym syms) allFindings + pure $ Right $ SymbolScanResult + { ssrRootSymbol = rootSym + , ssrReachable = Set.size syms + , ssrLineMap = lineMap + , ssrFindings = filtered + } + -- | Output NCT scan results for a specific symbol and its callees. outputNctSymbol :: Options -> SymbolScanResult -> IO () outputNctSymbol opts ssr = do