-
Notifications
You must be signed in to change notification settings - Fork 520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ New Probe: Memory safety #4499
base: main
Are you sure you want to change the base?
Conversation
a159254
to
56f3ef7
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4499 +/- ##
==========================================
+ Coverage 66.80% 68.34% +1.54%
==========================================
Files 230 248 +18
Lines 16602 18763 +2161
==========================================
+ Hits 11091 12824 +1733
- Misses 4808 5089 +281
- Partials 703 850 +147 |
here are some repos to test the code: go run main.go --repo github.com/microsoft/midi --probes memorysafe --format probe (.net unsafe code) |
Hoping to have some time to look at this tomorrow. Quick question about organization:
Probes are usually one specific behavior. In this case, the probe is concerned with looking for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't quite go through the tests yet, since the semantics of the probe will probably change through this discussion.
probes/memorysafe/impl.go
Outdated
"Golang code uses the unsafe package", &finding.Location{ | ||
Path: path, | ||
}, finding.OutcomeFalse) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have much more info than path available if we use :
https://pkg.go.dev/go/ast#ImportSpec.Pos and https://pkg.go.dev/go/ast#ImportSpec.End
Something like:
position := fset.Position(i.Pos())
and then we have access to line info too and can set finding. LineStart
. https://pkg.go.dev/go/token#Position
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added linestart. do you think any other information should be added?
the intention of this probe is to save the end user the need to know which best practices they are expected to have in the repo, and to give them a kind of a one stop shop for finding out if there's anything they're missing. Our goal was to try and implement the different practices that are suggested in the memory safety guides for memory-safe-by-default and non-memory-safe-by-default guides into this single probe. |
On the other hand, our goal for probes is that consumers are concerned with specific behavior and by having them do one thing it's easier to build policy. |
ok, so just for clarity, for this PR do you want to separate also to two different probes (one for c# and one for go)? |
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
* feat: create binary without OS and arch in name Previously binaries were created with their architecture and OS included as part of their binary name. Removing the `binary: scorecard-<linux|darwin|windows>-{{ .Arch }}` line allows us to collapse all of the different build configs into a single universal build that caters for [linux,darwin,windos]*[arm64,amd64] `- -buildmode=exe` was not needed on the windows builds and was also removed. closes ossf#4517 Signed-off-by: Tim Sparg <6872586+timothysparg@users.noreply.github.com> * fix: resolve name_template deprecation As per https://goreleaser.com/deprecations#snapshotname_template `snapshot.name_template` has been replaced with `snapshot.version_template` Signed-off-by: Tim Sparg <6872586+timothysparg@users.noreply.github.com> --------- Signed-off-by: Tim Sparg <6872586+timothysparg@users.noreply.github.com> Signed-off-by: balteravishay <avishay.balter@gmail.com>
* add git handler for GitHub repositories This is primarily aimed at helping in cases where a repository's .gitattributes file causes files to not be analyzed. Signed-off-by: Spencer Schrock <sschrock@google.com> * use variadic options to configure GitHub repoclient This will let us use the new entrypoint in a backwards compatible way, similar to the scorecard.Run change made in the v5 release. Signed-off-by: Spencer Schrock <sschrock@google.com> * add flag to enable github git mode Signed-off-by: Spencer Schrock <sschrock@google.com> * rename flag to be forge agnostic export-ignore is not a github specific feature, and other forges, like gitlab, suffer from the same bug. Signed-off-by: Spencer Schrock <sschrock@google.com> * move git file handler to internal package This will allow sharing with GitLab in a followup PR Signed-off-by: Spencer Schrock <sschrock@google.com> * add a test Signed-off-by: Spencer Schrock <sschrock@google.com> * use new toplevel gitmode argument also moves a func around for smaller PR diff. Signed-off-by: Spencer Schrock <sschrock@google.com> * add path traversal test Signed-off-by: Spencer Schrock <sschrock@google.com> * change flag to file-mode Signed-off-by: Spencer Schrock <sschrock@google.com> * fix repo typo in options test the value isn't used to connect to anything though. Signed-off-by: Spencer Schrock <sschrock@google.com> --------- Signed-off-by: Spencer Schrock <sschrock@google.com> Signed-off-by: balteravishay <avishay.balter@gmail.com>
go-git is not thread-safe, so the old method would lead to race conditions when multiple checks called ListFiles at the same time. This was reproducible when built with `-race`, and now no longer occurs because it's done inside a sync.Once. Signed-off-by: Spencer Schrock <sschrock@google.com> Signed-off-by: balteravishay <avishay.balter@gmail.com>
Signed-off-by: balteravishay <avishay.balter@gmail.com>
0ed8dcc
to
208b23c
Compare
@spencerschrock, this is now fixed to only test unsafe code blocks. |
Thanks will take a look today or tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a few minor things to fix
outcome: | ||
- For supported ecosystem, the probe returns OutcomeFalse per unsafe block. | ||
- If the project has no unsafe blocks, the probe returns OutcomeTrue. | ||
remediation: | ||
onOutcome: False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems inverted with what I would expect
unsafeblock would return true if there are unsafe blocks.
prominentLangs, err := getLanguageChecks(raw) | ||
if err != nil { | ||
return nil, Probe, err | ||
} | ||
findings := []finding.Finding{} | ||
for _, lang := range prominentLangs { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: prominentLangs
-> langs
"prominent" is something the fuzzing check to imply a language has a higher than average amount of lines of code. here you're just concerned with languages in the repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alternatively, do we even need to use the languages? checkDotnetAllowUnsafeBlocks
and checkGoUnsafePackage
are limited to .go
and .csproj
files. Although I assume there's a speed benefit as written here for projects that aren't written in either Go or C#.
found, err := finding.NewWith(fs, Probe, | ||
"All supported ecosystems do not declare or use unsafe code blocks", nil, finding.OutcomeTrue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned elsewhere, the outcome is flipped from what I would expect.
if len(langs) == 0 { | ||
return []languageMemoryCheckConfig{}, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this seems redundant as not entering the loop would produce the same result.
found, err := finding.NewWith(fs, Probe, | ||
"Golang code uses the unsafe package", &finding.Location{ | ||
Path: path, LineStart: &lineStart, | ||
}, finding.OutcomeFalse) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flagging outcome flip
return os.Open(file) | ||
}).AnyTimes() | ||
raw.RepoClient = mockRepoClient | ||
raw.Dlogger = checker.NewLogger() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
normally in tests we use the TestDetailLogger
Lines 38 to 41 in 3b42b6e
// TestDetailLogger implements `checker.DetailLogger`. | |
type TestDetailLogger struct { | |
messages []checker.CheckDetail | |
} |
return nil, fmt.Errorf("error") | ||
}).AnyTimes() | ||
raw.RepoClient = mockRepoClient | ||
raw.Dlogger = checker.NewLogger() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment about logger
return nil, fmt.Errorf("error") | ||
}).AnyTimes() | ||
raw.RepoClient = mockRepoClient | ||
raw.Dlogger = checker.NewLogger() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logger
What kind of change does this PR introduce?
This PR provides the foundation for addressing issue #3736 by adding a new probe that checks if the code uses non memory safe practices for the repository languages.
The goal is to automate the detection of as many of the practices that the memory safety SIG provides under the Best Practices - Memory-Safe By Default Languages and the Best Practices - Non Memory-Safe By Default Languages guides.
What is the current behavior?
Today scorecard does not detect memory safe practices in it's core features or in any of the probes.
What is the new behavior (if this is a feature change)?**
Probe detects the following:
for golang it detects if the code imports the unsafe package and points to the locations where it is used.
for c# it detects if the projects allow for unsafe blocks which is a requirement for any project that would use any form of .Net unsafe code, pointer types, and function pointers
Tests for the changes have been added (for bug fixes/features)
Which issue(s) this PR fixes
This code change addresses issue #3736 but does not close it (to be discussed)
Special notes for your reviewer
This code change and the implementation of it were discussed in scorecard community calls with @spencerschrock
Does this PR introduce a user-facing change?
For user-facing changes, please add a concise, human-readable release note to
the
release-note
(In particular, describe what changes users might need to make in their
application as a result of this pull request.)