fix(sourceanalysis): return an error instead of exiting when an rlib has no object file - #2977
fix(sourceanalysis): return an error instead of exiting when an rlib has no object file#2977kobihikri wants to merge 2 commits into
Conversation
…has no object file extractRlibArchive called log.Fatalf on any error from the archive iterator, including the io.EOF that ends every ar archive. An archive with no "/0" member and no ".rcgu.o/" member walks the loop to end-of-archive and exits the process. The caller at rust.go:53-57 already logs the error and continues to the next artifact, but log.Fatalf exits before the error can be returned, so one unrelated build artifact ends the whole scan. It also reports the wrong exit code. log.Fatalf exits 1, which docs/output.md reserves for "packages were found when scanning, and there are vulnerabilities or findings" — a result-related code. An internal failure should be 127. Treat end-of-archive as "this is not an rlib we can analyse" and return an error, letting the existing continue skip the artifact and the scan finish normally. This was the only log.Fatalf in non-test library code. Fixes google#2976
|
Please read our contributing guide before opening pull requests |
G-Rath
left a comment
There was a problem hiding this comment.
The code change and test look fine, but could you scale back the comments?
Personally I'd say the test is a nice extra bit of coverage rather than guarding against a specific "fix" - the fact that this was a log.Fatal previously is discoverable from the git history, and us returning an error rather than exiting immediately is very standard behaviour so shouldn't need to be called out anywhere.
Drop the comments describing the previous log.Fatal behaviour and the one framing the test as guarding a specific fix; the git history carries that. Code and test logic are unchanged. Signed-off-by: Kobi Hikri <kobi.hikri@gmail.com>
|
Thanks — that's fair, the git history does carry it. I've dropped the comments narrating the old Re-ran at your pinned golangci-lint v2.11.4 (0 issues), |
Overview
Fixes #2976.
extractRlibArchivecallslog.Fatalfon any error from the archive iterator, including theordinary
io.EOFthat ends every ar archive. An ar archive with no/0member and no.rcgu.o/member walks the loop to end-of-archive and terminates the whole
osv-scannerprocess.This came out of GHSA-2f6x-xr4j-f2h7. @another-rex judged it a regular bug rather than a
vulnerability and I agree with him — the process exits non-zero, so nothing is silently hidden.
Opening it here as the bug it is.
Details
Two things were wrong, and both are fixed by returning the error:
1. One artifact ended the entire scan. The caller is already written to survive this:
log.Fatalfisos.Exit(1), so it exits before that error can be returned and thecontinuenever runs.
2. The exit code was wrong.
docs/output.mdreserves1for "packages were found whenscanning, and there are vulnerabilities or findings" and
127for General Error.log.Fatalfexits
1, so an internal failure was reported to CI through a result-related code, and no outputwas produced. Letting the scan finish normally removes the ambiguity.
The change treats end-of-archive as "this is not an rlib we can analyse" and returns an error;
any other error is wrapped and returned. The
logimport goes with it — this was the onlylog.Fatalfin non-test library code.No malformed or hostile input is needed to hit this: a well-formed ar archive that simply is not a
Rust rlib is enough (
ar rc plain.a a.txt).Testing
Added
Test_extractRlibArchive_noObjectFile, which builds a minimal GNU ar archive by hand(so the test needs no
arbinary on the machine running it) and asserts an error is returned.Verified the test actually catches the regression. Against the unpatched
rust.goit doesnot merely fail an assertion — the test binary is killed mid-test by
os.Exit(1):With the fix:
--- PASS: Test_extractRlibArchive_noObjectFile (0.00s).The existing
Test_extractRlibArchivecases (simple.rlib,medium.rlib) still pass; the newfixture is written to
t.TempDir()so it is not picked up by that directory-driven test.go test ./internal/sourceanalysis/...— ok.golangci-lintat your pinnedv2.11.4on the package — 0 issues.gofmt -lclean,go vetclean.
All run in a
golang:1.26container matchinggo.mod.Checklist
./scripts/run_lints.sh. (golangci-lintv2.11.4on the changed package — 0 issues)./scripts/run_tests.sh. (go test ./internal/sourceanalysis/...— ok)I used an AI assistant while investigating this; I read the code paths, wrote the test, and ran the
verification myself.