Skip to content

fix: correctly report supporting evidence for binary packages#4558

Merged
kzantow merged 7 commits intoanchore:mainfrom
kzantow-anchore:fix/go-version-file-as-primary-evidence
Jan 23, 2026
Merged

fix: correctly report supporting evidence for binary packages#4558
kzantow merged 7 commits intoanchore:mainfrom
kzantow-anchore:fix/go-version-file-as-primary-evidence

Conversation

@kzantow
Copy link
Contributor

@kzantow kzantow commented Jan 16, 2026

Description

This PR adjusts the binary classifier to more appropriately return "supporting" evidence locations marked as such rather than being marked as "primary". This primarily affects go, ruby, and python binary classifiers, where each of these looks at files beyond the binary executable if it can't find version information in the executable directly, for example: python searches for a matching libpython and go searches for a VERSION file containing something that looks like a go version. The logic has also been tweaked slightly so a VERSION file without a go binary does not return a package.

Before this change, multiple locations would be returned all with primary evidence e.g.:

    {
      "id": "d21881475fd270e3",
      "name": "go",
      "version": "1.18.1",
      "type": "binary",
      "foundBy": "binary-classifier-cataloger",
      "locations": [
        {
          "path": "/usr/local/go/VERSION",
          "layerID": "sha256:f55ac134ae7cb1b43fb9caeeb11f6d64219f062f8731ac76b6ece357aa6d73b0",
          "accessPath": "/usr/local/go/VERSION",
          "annotations": {
            "evidence": "primary"
          }
        },
        {
          "path": "/usr/local/go/bin/go",
          "layerID": "sha256:f55ac134ae7cb1b43fb9caeeb11f6d64219f062f8731ac76b6ece357aa6d73b0",
          "accessPath": "/usr/local/go/bin/go",
          "annotations": {
            "evidence": "primary"
          }
        }
      ],
...

After this PR, a user may see:

    {
      "id": "d21881475fd270e3",
      "name": "go",
      "version": "1.18.1",
      "type": "binary",
      "foundBy": "binary-classifier-cataloger",
      "locations": [
        {
          "path": "/usr/local/go/bin/go",
          "layerID": "sha256:f55ac134ae7cb1b43fb9caeeb11f6d64219f062f8731ac76b6ece357aa6d73b0",
          "accessPath": "/usr/local/go/bin/go",
          "annotations": {
            "evidence": "primary"
          }
        },
        {
          "path": "/usr/local/go/VERSION",
          "layerID": "sha256:f55ac134ae7cb1b43fb9caeeb11f6d64219f062f8731ac76b6ece357aa6d73b0",
          "accessPath": "/usr/local/go/VERSION",
          "annotations": {
            "evidence": "supporting"
          }
        }
      ],
...

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have added unit tests that cover changed behavior
  • I have tested my code in common scenarios and confirmed there are no regressions
  • I have added comments to my code, particularly in hard-to-understand sections

Issue references

Signed-off-by: Keith Zantow <kzantow@gmail.com>
@kzantow kzantow marked this pull request as draft January 16, 2026 21:09
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Keith Zantow <kzantow@gmail.com>
@kzantow kzantow marked this pull request as ready for review January 22, 2026 20:01
t.Fatalf("locations do not match; expected: %v got: %v", expectedLocations, gotLocations)
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Locations are already being tested below, in assertPackagesAreEqual 👇

Comment on lines 2012 to +2019
if len(expectedLocations) != len(gotLocations) {
failMessages = append(failMessages, "locations are not equal length")
failMessages = append(failMessages, fmt.Sprintf("locations are not equal: %v != %v", expectedLocations, gotLocations))
} else {
for i, expectedLocation := range expectedLocations {
gotLocation := gotLocations[i]
if expectedLocation.RealPath != gotLocation.RealPath {
failMessages = append(failMessages, fmt.Sprintf("locations do not match; expected: %v got: %v", expectedLocation.RealPath, gotLocation.RealPath))
for _, expectedLocation := range expectedLocations {
if !slices.ContainsFunc(gotLocations, func(gotLocation file.Location) bool {
return gotLocation.RealPath == expectedLocation.RealPath
}) {
failMessages = append(failMessages, fmt.Sprintf("location not found; expected: %v in set: %v", expectedLocation.RealPath, gotLocations))
Copy link
Contributor Author

@kzantow kzantow Jan 22, 2026

Choose a reason for hiding this comment

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

These locations are not sorted identically in .ToSlice(), above, due to expected differences in evidence annotations. This change just asserts the sets contain the same elements, not the same order.

@kzantow kzantow changed the title fix: do not indicate go VERSION file is primary evidence fix: correctly report supporting evidence for binary packages Jan 22, 2026
Copy link
Contributor

@spiffcs spiffcs left a comment

Choose a reason for hiding this comment

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

Approved with comment about a potential test typo

classifier: Classifier{
FileGlob: "**/some-binary",
EvidenceMatcher: SupportingEvidenceMatcher("../version.txt",
FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`)),
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a typo in the regex? my-verison vs my-version

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorta... a bit of a systemic typo, apparently! Fixed 👍

Signed-off-by: Keith Zantow <kzantow@gmail.com>
@kzantow kzantow merged commit 836f358 into anchore:main Jan 23, 2026
10 checks passed
@kzantow kzantow deleted the fix/go-version-file-as-primary-evidence branch January 23, 2026 18:01
kzantow added a commit that referenced this pull request Jan 26, 2026
Signed-off-by: Keith Zantow <kzantow@gmail.com>
@willmurphyscode willmurphyscode added the bug Something isn't working label Jan 27, 2026
spiffcs added a commit to patrickpichler/syft that referenced this pull request Jan 30, 2026
* main: (114 commits)
  fix: lookup alternate scheme on url->licenseID (anchore#4588)
  chore(deps): bump the go-minor-patch group with 2 updates (anchore#4583)
  feat: add Qt6 binary detection (anchore#4550)
  chore(deps): bump the actions-minor-patch group across 1 directory with 2 updates (anchore#4584)
  fix: snap cataloger incorrectly identifies snap container as deb package (anchore#4500)
  chore(deps): update tools to latest versions (anchore#4577)
  fix: update mixed case dependencies in python to be normalized (anchore#4573)
  chore(deps): update anchore dependencies (anchore#4575)
  chore(deps): update tools to latest versions (anchore#4570)
  feat: detect Debian version from /etc/debian_version (anchore#4569)
  fix: correctly report supporting evidence for binary packages (anchore#4558)
  chore(deps): bump the actions-minor-patch group across 2 directories with 3 updates (anchore#4568)
  chore(deps): bump the go-minor-patch group with 6 updates (anchore#4567)
  chore(deps): update tools to latest versions (anchore#4565)
  chore(deps): bump github.com/spdx/tools-golang (anchore#4557)
  ci: enable zizmor to fail PRs (anchore#4556)
  Chore new slack action (anchore#4553)
  chore(deps): update anchore dependencies (anchore#4552)
  chore(deps): update tools to latest versions (anchore#4551)
  chore(deps): update tools to latest versions (anchore#4545)
  ...

Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
westonsteimel added a commit to anchore/vulnerability-match-labels that referenced this pull request Feb 2, 2026
…o longer considered

Due to the following PRs in syft, some matches which were previously TPs
should now be considered FPs:

- anchore/syft#4231
- anchore/syft#4558

Signed-off-by: Weston Steimel <author@code.w.steimel.me.uk>
westonsteimel added a commit to anchore/vulnerability-match-labels that referenced this pull request Feb 2, 2026
…o longer considered (#179)

Due to the following PRs in syft, some matches which were previously TPs
should now be considered FPs:

- anchore/syft#4231
- anchore/syft#4558

Signed-off-by: Weston Steimel <author@code.w.steimel.me.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants