diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 4b4e2ed7d..54cd04f3b 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -407,6 +407,30 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("traefik-binary"), }, }, + { + // regression test: big-endian architectures (e.g. s390x) previously matched an unrelated + // single-NUL-terminated numeric string elsewhere in the binary instead of the real version + logicalFixture: "traefik/3.6.8/linux-s390x", + expected: pkg.Package{ + Name: "traefik", + Version: "3.6.8", + Type: "binary", + PURL: "pkg:generic/traefik@3.6.8", + Locations: locations("traefik"), + Metadata: metadata("traefik-binary"), + }, + }, + { + logicalFixture: "traefik/2.11.1/linux-arm", + expected: pkg.Package{ + Name: "traefik", + Version: "2.11.1", + Type: "binary", + PURL: "pkg:generic/traefik@2.11.1", + Locations: locations("traefik"), + Metadata: metadata("traefik-binary"), + }, + }, { logicalFixture: "memcached/1.6.18/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 17834ab0c..26929ae2a 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -284,11 +284,18 @@ func DefaultClassifiers() []binutils.Classifier { { Class: "traefik-binary", FileGlob: "**/traefik", - EvidenceMatcher: m.FileContentsVersionMatcher( + EvidenceMatcher: binutils.MatchAny( + // on some architectures (e.g. s390x) the real version string isn't NUL-prefixed + // and is instead terminated by two NUL bytes; checking this pattern first avoids + // matching an unrelated single-NUL-terminated numeric string elsewhere in the binary + m.FileContentsVersionMatcher( + `(?m)(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00\x00`), // [NUL]v1.7.34[NUL] // [NUL]2.9.6[NUL] // 3.0.4[NUL] - `(?m)(\x00v?|\x{FFFD}.?)(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`), + m.FileContentsVersionMatcher( + `(?m)(\x00v?|\x{FFFD}.?)(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`), + ), Package: "traefik", PURL: mustPURL("pkg:generic/traefik@version"), CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/traefik/2.11.1/linux-arm/traefik b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/traefik/2.11.1/linux-arm/traefik new file mode 100644 index 000000000..f0be458f0 Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/traefik/2.11.1/linux-arm/traefik differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/traefik/3.6.8/linux-s390x/traefik b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/traefik/3.6.8/linux-s390x/traefik new file mode 100644 index 000000000..0141469f6 Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/traefik/3.6.8/linux-s390x/traefik differ