Suppress ERR997 (PDB not found) for IL-only managed assemblies
Summary
ERR997.ExceptionLoadingPdb fires for IL-only managed assemblies (including satellite resource assemblies) even though no current BinSkim rule requires PDB data for IL-only binaries. This creates significant noise in scan results — for example, scanning dotnet/dotnet macOS artifacts produces thousands of ERR997 entries, all on IL-only assemblies, none actionable.
Resource assemblies are produced by AL (the managed linker) and have zero code and no PDB. So this is pure noise for anyone that ships localized resources.
What should happen: ERR997 should not happen for IL-only assemblies UNLESS a rule actually needs the PDB for an IL-only assembly, and none of the rules in this repo do.
Root cause
In WindowsBinaryAndPdbSkimmerBase.Analyze() (line 50-59), the condition that gates ERR997 is:
if (target.Pdb == null &&
(!target.PE.IsManaged ||
target.PE.IsMixedMode ||
EnforcePdbLoadForManagedAssemblies))
For an IL-only managed assembly (IsManaged=true, IsMixedMode=false), this evaluates to (!true || false || true) = true, so ERR997 fires and the rule is skipped entirely (return at line 58).
EnforcePdbLoadForManagedAssemblies defaults to true and no rule in the repo overrides it. The only two PDB-using rules that apply to IL-only assemblies (BA2004 and BA2027) both use a different mechanism — they override LogPdbLoadException => false and handle null PDB gracefully in their AnalyzePortableExecutableAndPdb().
Proposed fix
1. Remove EnforcePdbLoadForManagedAssemblies from the ERR997 condition:
// Before:
if (target.Pdb == null &&
(!target.PE.IsManaged ||
target.PE.IsMixedMode ||
EnforcePdbLoadForManagedAssemblies))
// After:
if (target.Pdb == null &&
(!target.PE.IsManaged ||
target.PE.IsMixedMode))
This means:
- Native binaries: ERR997 still fires (PDB is critical for native-code rules)
- Mixed-mode: ERR997 still fires (has native code that needs PDB analysis)
- IL-only managed: ERR997 suppressed, rule proceeds with
Pdb=null. Rules that need PDB already handle null gracefully in their AnalyzePortableExecutableAndPdb().
2. Mark EnforcePdbLoadForManagedAssemblies as obsolete (it's public virtual, so removing it would be a breaking change):
[Obsolete("This property is no longer used. IL-only managed assemblies no longer trigger "
+ "ERR997. Rules that require PDB for managed assemblies should check for null PDB "
+ "in their AnalyzePortableExecutableAndPdb implementation.")]
public virtual bool EnforcePdbLoadForManagedAssemblies => true;
Why this is safe
- No rule overrides
EnforcePdbLoadForManagedAssemblies — grep confirms zero overrides in the repo.
- The only two PDB rules applicable to IL-only (BA2004, BA2027) already override
LogPdbLoadException => false and check if (pdb == null) { return; } in their analysis methods.
- All other PDB rules (BA2002, BA2006, BA2007, BA2011, BA2013, BA2014, BA2024, BA2026) return
NotApplicableToSpecifiedTarget for IL-only assemblies in CanAnalyzePE, so they never reach Analyze().
- Future rules that need PDB for IL-only assemblies should handle null PDB in
AnalyzePortableExecutableAndPdb() — this is the correct pattern already established by BA2004/BA2027.
Suppress ERR997 (PDB not found) for IL-only managed assemblies
Summary
ERR997.ExceptionLoadingPdbfires for IL-only managed assemblies (including satellite resource assemblies) even though no current BinSkim rule requires PDB data for IL-only binaries. This creates significant noise in scan results — for example, scanning dotnet/dotnet macOS artifacts produces thousands of ERR997 entries, all on IL-only assemblies, none actionable.Resource assemblies are produced by AL (the managed linker) and have zero code and no PDB. So this is pure noise for anyone that ships localized resources.
What should happen: ERR997 should not happen for IL-only assemblies UNLESS a rule actually needs the PDB for an IL-only assembly, and none of the rules in this repo do.
Root cause
In
WindowsBinaryAndPdbSkimmerBase.Analyze()(line 50-59), the condition that gates ERR997 is:For an IL-only managed assembly (
IsManaged=true,IsMixedMode=false), this evaluates to(!true || false || true)=true, so ERR997 fires and the rule is skipped entirely (returnat line 58).EnforcePdbLoadForManagedAssembliesdefaults totrueand no rule in the repo overrides it. The only two PDB-using rules that apply to IL-only assemblies (BA2004 and BA2027) both use a different mechanism — they overrideLogPdbLoadException => falseand handle null PDB gracefully in theirAnalyzePortableExecutableAndPdb().Proposed fix
1. Remove
EnforcePdbLoadForManagedAssembliesfrom the ERR997 condition:This means:
Pdb=null. Rules that need PDB already handle null gracefully in theirAnalyzePortableExecutableAndPdb().2. Mark
EnforcePdbLoadForManagedAssembliesas obsolete (it'spublic virtual, so removing it would be a breaking change):Why this is safe
EnforcePdbLoadForManagedAssemblies— grep confirms zero overrides in the repo.LogPdbLoadException => falseand checkif (pdb == null) { return; }in their analysis methods.NotApplicableToSpecifiedTargetfor IL-only assemblies inCanAnalyzePE, so they never reachAnalyze().AnalyzePortableExecutableAndPdb()— this is the correct pattern already established by BA2004/BA2027.