Skip to content

[WIP] Add BA2027.EnableSourceLink#657

Merged
michaelcfanning merged 12 commits into
microsoft:mainfrom
pharring:main
Jul 14, 2022
Merged

[WIP] Add BA2027.EnableSourceLink#657
michaelcfanning merged 12 commits into
microsoft:mainfrom
pharring:main

Conversation

@pharring
Copy link
Copy Markdown
Member

Fixes #656

A few notes:

The version of Dia2Lib that we use is a bit out of date. I need IDiaDataSource3 to get access to the raw stream data, so I redefined it locally for now.

I created a SourceLink.sln under src/BuildSamples to generate combinations of C#/C++ with/without SourceLink. The outputs of these builds are then checked in under FunctionalTestData. I also grabbed a couple of existing clang/gcc/macho binaries to test the "NotApplicable" code path.

Comment thread src/BinaryParsers/PEBinary/PortableExecutable/PE.cs Fixed
Comment thread src/BinaryParsers/PEBinary/PortableExecutable/PE.cs Fixed
Comment thread src/BinaryParsers/PEBinary/PortableExecutable/PE.cs Fixed
@marmegh
Copy link
Copy Markdown
Contributor

marmegh commented Jun 23, 2022

I see you added test binaries to the functional test folder. You'll want to run UpdateBaselines.cmd to automatically generate/update a SARIF file for each test binary including the new rule. Make sure to run BuildAndTest before and after executing this step. It is likely that some tests may no longer be up to date with the rule addition.

@pharring pharring changed the title Add BA6001.EnableSourceLink [WIP] Add BA6001.EnableSourceLink Jun 23, 2022
@pharring pharring marked this pull request as draft June 23, 2022 06:16
@pharring
Copy link
Copy Markdown
Member Author

  1. Need to update baselines.
  2. Need to fix unit tests.

@pharring pharring marked this pull request as ready for review June 24, 2022 19:37
@pharring pharring changed the title [WIP] Add BA6001.EnableSourceLink Add BA6001.EnableSourceLink Jun 24, 2022
Comment thread src/BinaryParsers/PEBinary/ProgramDatabase/Pdb.cs
Comment thread docs/BinSkimRules.md Outdated
Comment thread docs/BinSkimRules.md Outdated
Comment thread src/BinSkim.Rules/RuleIds.cs Outdated
Comment thread src/BinSkim.Rules/PERules/BA6001.EnableSourceLink.cs Outdated
Comment thread src/BinSkim.Rules/RuleIds.cs Outdated
Comment thread src/BuildSamples/SourceLink/Directory.Build.targets
}
],
"message": {
"text": "'Binskim.linux-x64.dll' was not evaluated because its PDB could not be loaded (E_PDB_FORMAT)."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PDB could not be loaded

In general, any transition you see from 'executionSuccessful' == true to the appearance of error notifications will be a usability problem.

We need to chase down these 'PDB can't be loaded' issues.

Several high-level matters will be helpful to settle: 1) you need to make sure your PDB loading only occurs when the target is valid for your analysis, 2) you need to make sure your analysis only occurs if you observe the binary is built with a toolchain that provides source-link support.

i.e., we don't generally push for things like 'you need to update your stale compiler toolchain so you can enable sourcelink'. The pressure to upgrade is handled in the 'BuildWithSecureTools' rule. Assuming that rule is enforcing a min-version that also enables SourceLink, all we need to do is update that rule docs to mention SourceLink as yet another motivation to upgrade your compiler.

You may discover the min-version that rule enforces is too early for SourceLink support, in which case we should consider lifting it.

"invocations": [
{
"executionSuccessful": true
"toolConfigurationNotifications": [
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toolConfigurationNotifications

This notification is a concern because it suggests we used to successfully analyze this binary but now cannot, because we are (for the first time) attempting to location a PDB for it. This could indicate that your rule's CanAnalyze needs to be filtering something it is not. In any case, the new appearance of E_PDB_NO_DEBUG_INFO is probably something we shouldn't see in your baseline updates.


public override AnalysisApplicability CanAnalyzePE(PEBinary target, PropertiesDictionary policy, out string reasonForNotAnalyzing)
{
reasonForNotAnalyzing = null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reasonForNotAnalyzing

Ah, here we are. There are many N/A conditions you probably should be honoring. I think. :) For example, do we require source code in a resource-only binary? Or any case in which a PDB (if one exists) might not have source records? Is that possible?

Comment thread src/BinSkim.Rules/PERules/BA6001.EnableSourceLink.cs Outdated
Comment thread src/BinSkim.Rules/PERules/BA6001.EnableSourceLink.cs Outdated
// not whether they can be read.
if (pdb.FileType == PdbFileType.Portable)
{
string sourceLinkDocument = target.PE.ManagedPdbGetSourceLinkDocument(pdb);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't actually read this document, is there a more efficient API we could create that simply notices where the reader has content? Looking at your helper, can we avoid the ReadUTF8 call and just return true because its Length is >0? That would save something wouldn't it?

return sourceLinkReader.Length == 0 ? null : sourceLinkReader.ReadUTF8(sourceLinkReader.Length);

else
{
IEnumerable<string> sourceLinkDocuments = pdb.WindowsPdbGetSourceLinkDocuments();
return sourceLinkDocuments != null && sourceLinkDocuments.Any();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any

Looking at your yield iterator implementation, looks like this code path is as efficient as it could be, i.e., breaks on the first evidence we've got support.

Just asking: is there no magic value, other (reliable) heuristic we can use to make this determination? I ask merely because as a rule, we try to avoid PDB parsing (and COM interop) wherever possible. Sniffing a magic file in a binary is admirably low-cost. :)

My sense is there's no opportunity here and we've got a reasonably efficient implementation (save the unnecessary presence of ReadUTF8 in the Portable code path, if I'm correct there's a fix we could make here).

Copy link
Copy Markdown
Contributor

@shaopeng-gh shaopeng-gh Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read form the test file i can see the linker commandline have the:
/sourcelink

/ERRORREPORT:PROMPT /OUT:V:\T\binskim\src\BuildSamples\SourceLink\x64\Release\CPlusPlus_SourceLink.exe /NOLOGO /MANIFEST "/MANIFESTUAC:level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:V:\T\binskim\src\BuildSamples\SourceLink\x64\Release\CPlusPlus_SourceLink.pdb /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG:incremental /LTCGOUT:x64\Release\CPlusPlus_SourceLink.iobj /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:V:\T\binskim\src\BuildSamples\SourceLink\x64\Release\CPlusPlus_SourceLink.lib /MACHINE:X64 /sourcelink:x64\Release\CPlusPlus_SourceLink.sourcelink.json

https://docs.microsoft.com/en-us/cpp/build/reference/sourcelink?view=msvc-170

@pharring pharring changed the title Add BA6001.EnableSourceLink [WIP] Add BA2027.EnableSourceLink Jul 13, 2022
pharring added 3 commits July 12, 2022 21:39
Add well-known compiler detection for clang and rust
Update pass/fail messages
Add test cases for rust and clang
Other PR feedback
Comment thread src/BinSkim.Rules/PERules/BA2027.EnableSourceLink.cs Fixed
Comment thread src/BinSkim.Rules/PERules/BA2027.EnableSourceLink.cs Fixed
Copy link
Copy Markdown
Member

@michaelcfanning michaelcfanning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@michaelcfanning michaelcfanning enabled auto-merge (squash) July 14, 2022 22:02
@michaelcfanning michaelcfanning disabled auto-merge July 14, 2022 22:02
@michaelcfanning
Copy link
Copy Markdown
Member

@pharring, this is approved. First, I've made you a write contributor to this codebase, so please feel free to simply create branches off main for future PRs. Second, we have a problem in a pipeline (that apparently can't build your fork) which is prevent us from merging your change. We are working on that. :)

@michaelcfanning michaelcfanning merged commit 32e56ee into microsoft:main Jul 14, 2022
Comment thread .gitignore
*.meta
*.obj
*.pch
*.pdb
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we can use the folder ignore it would be better,

above:
# Build results bld/ bin/ obj/

this particular one *.pdb since we frequently checking in pdb files

Comment thread docs/BinSkimRules.md
## Rule `BA3030.UseCheckedFunctionsWithGcc`

### Description

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C#

Does it support VB?

Source Link is a language- and source-control agnostic system for providing first-class source debugging experiences for binaries...

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.

[RULE REQUEST] Warn when SourceLink information is missing

5 participants