Skip to content

BA3003: report NotApplicable for Rust-only binaries#1192

Open
himaja-kesari wants to merge 1 commit into
microsoft:mainfrom
himaja-kesari:fix/ba3003-rust-not-applicable
Open

BA3003: report NotApplicable for Rust-only binaries#1192
himaja-kesari wants to merge 1 commit into
microsoft:mainfrom
himaja-kesari:fix/ba3003-rust-not-applicable

Conversation

@himaja-kesari
Copy link
Copy Markdown

Summary

rustc-built ELF binaries are currently always reported as error BA3003 ("stack protector not found"), even when Rust stack protection is enabled. This PR makes BA3003 report NotApplicable for binaries whose only DWARF producer is rustc.

Why

BA3003 has two detection paths for ELF:

  1. DWARF: look for a GCC compile unit whose producer command line contains -fstack-protector-strong / -fstack-protector-all.
  2. Symbol fallback (only when no GCC compile units are present): look for __stack_chk_fail, __stack_chk_guard, or __intel_security_cookie in the symbol table.

rustc:

  • does not produce GCC-style DWARF compile units, so path (1) yields zero valid entries;
  • enables stack protection through LLVM and does not emit __stack_chk_fail / __stack_chk_guard, so path (2) returns false.

Result: every rustc-only binary is reported as error BA3003 regardless of the actual stack-protection setting.

Change

In the ELF branch of Analyze, after building validGccCommandLineInfos, if:

  • the GCC list is empty, and
  • elf.Compilers contains ElfCompilerType.Rust, and
  • elf.Compilers does not contain ElfCompilerType.GCC

…then report ResultKind.NotApplicable (re-using the existing RuleResources.NotApplicable_InvalidMetadata message) with text explaining that the GCC stack-protector heuristic does not apply. Mixed C/Rust binaries (anything with at least one GCC CU) continue through the existing DWARF path unchanged.

Repro that motivated this

/usr/lib/dracut/dracut-cpio from Azure Linux 4 (dracut-107-9.azl4.x86_64.rpm) is a small rustc-built helper. BinSkim 4.4.x reports error BA3003 on it even though the Rust source enables stack protection. With this patch the same scan reports NotApplicable with a clear reason, matching the rule’s contract.

Testing

  • Builds clean against main (commit 696f2ba) with dotnet build src/BinSkim.Rules/BinSkim.Rules.csproj -c Release.
  • Verified locally with a self-contained linux-x64 publish that a rustc-only binary now reports NotApplicable while a GCC-built binary with the same flags is unchanged.

Happy to add a Rust binary fixture under Test.FunctionalTests.BinSkim.Driver/TestData/BA3003.EnableStackProtector/NotApplicable/ if maintainers can confirm the preferred way to commit a rustc-produced ELF into the repo.

rustc enables stack protection via LLVM and does not emit the
__stack_chk_fail / __stack_chk_guard / __intel_security_cookie
symbols that BA3003 looks for in its symbol-table fallback path.
It also does not produce GCC-style DWARF compile units, so the DWARF
path yields zero valid GCC entries and BA3003 falls through to the
symbol heuristic, which then false-flags every Rust binary as missing
a stack protector.

When the only producer recorded for the ELF is Rust (and there is no
GCC compile unit), report ResultKind.NotApplicable instead, with a
message explaining that the GCC heuristic does not apply to this
binary. This matches the behavior the rule already uses for other
NotApplicable cases via RuleResources.NotApplicable_InvalidMetadata.

No behavior change for binaries that contain at least one GCC compile
unit (mixed C/Rust links still go through the DWARF path).
@himaja-kesari himaja-kesari requested a review from a team as a code owner May 28, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant