From 9f956dca8fc4874e8b9c4a092503236a8d6349cb Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Tue, 12 Aug 2025 08:58:28 -0400 Subject: [PATCH] fix: closed reader during java binary detection (#4129) Signed-off-by: Keith Zantow --- .../binary/classifier_cataloger_test.go | 33 ---------- syft/pkg/cataloger/binary/classifiers_java.go | 34 +++++----- .../cataloger/binary/classifiers_java_test.go | 66 +++++++++++++++++++ .../binary/test-fixtures/config.yaml | 27 -------- .../image-java-binary/Dockerfile | 1 + .../test-fixtures/image-java-ibm-8/Dockerfile | 6 ++ .../image-java-ibm-jre-8/Dockerfile | 6 ++ .../image-java-ibm-sdk-8/Dockerfile | 6 ++ .../image-java-zulu-21/Dockerfile | 5 ++ .../image-java-zulu-8/Dockerfile | 5 ++ .../internal/binutils/branching_matcher.go | 10 ++- 11 files changed, 121 insertions(+), 78 deletions(-) create mode 100644 syft/pkg/cataloger/binary/classifiers_java_test.go create mode 100644 syft/pkg/cataloger/binary/test-fixtures/image-java-binary/Dockerfile create mode 100644 syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-8/Dockerfile create mode 100644 syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-jre-8/Dockerfile create mode 100644 syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-sdk-8/Dockerfile create mode 100644 syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-21/Dockerfile create mode 100644 syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-8/Dockerfile diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 70d4aebe7..69bce23a5 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -775,39 +775,6 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("java-binary-oracle", "java"), }, }, - { - logicalFixture: "java-jre-ibm/1.8.0_391/linux-amd64", - expected: pkg.Package{ - Name: "java", - Version: "1.8.0-foreman_2023_10_12_13_27-b00", - Type: "binary", - PURL: "pkg:generic/ibm/java@1.8.0-foreman_2023_10_12_13_27-b00", - Locations: locations("java"), - Metadata: metadata("java-binary-ibm", "java"), - }, - }, - { - logicalFixture: "java-ibm-8-jre/1.8.0_451/linux-amd64", - expected: pkg.Package{ - Name: "java", - Version: "1.8.0-_2025_04_14_02_37-b00", - Type: "binary", - PURL: "pkg:generic/ibm/java@1.8.0-_2025_04_14_02_37-b00", - Locations: locations("java"), - Metadata: metadata("java-binary-ibm", "java"), - }, - }, - { - logicalFixture: "java-ibm-8-sdk-alpine/1.8.0_321/linux-amd64", - expected: pkg.Package{ - Name: "java_sdk", - Version: "1.8.0-foreman_2022_01_20_09_33-b00", - Type: "binary", - PURL: "pkg:generic/ibm/java_sdk@1.8.0-foreman_2022_01_20_09_33-b00", - Locations: locations("jdb"), - Metadata: metadata("java-sdk-binary-ibm", "jdb"), - }, - }, { logicalFixture: "java-jdk-openjdk/21.0.2+13-LTS/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers_java.go b/syft/pkg/cataloger/binary/classifiers_java.go index af87dedd4..376e45e20 100644 --- a/syft/pkg/cataloger/binary/classifiers_java.go +++ b/syft/pkg/cataloger/binary/classifiers_java.go @@ -122,6 +122,23 @@ func defaultJavaClassifiers() []binutils.Classifier { PURL: mustPURL("pkg:generic/oracle/graalvm@version"), CPEs: singleCPE("cpe:2.3:a:oracle:graalvm_for_jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, + { + Class: "jdb-binary-openjdk-zulu", + EvidenceMatcher: binutils.MatchAll( + binutils.MatchPath("**/*zulu*/**"), + binutils.MatchAny( + m.FileContentsVersionMatcher( + // [NUL]jdb[NUL]0.0[NUL]11.0.17+8-LTS[NUL] + `(?m)(java|jdb)\x00(?P[0-9]+[.0-9]*)\x00(?P[0-9]+[^\x00]+)\x00`), + m.FileContentsVersionMatcher( + // arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]jdb[NUL] + `(?m)\x00(?P[0-9]+[.0-9]*)\x00+(?P[0-9]+[^\x00]+)\x00+(java|jdb)`), + ), + ), + Package: "zulu", + PURL: mustPURL("pkg:generic/azul/zulu@version"), + CPEs: singleCPE("cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + }, { Class: "java-jdb-binary-openjdk", EvidenceMatcher: binutils.MatchAll( @@ -137,23 +154,6 @@ func defaultJavaClassifiers() []binutils.Classifier { PURL: mustPURL("pkg:generic/oracle/openjdk@version"), CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, - { - Class: "jdb-binary-openjdk-zulu", - EvidenceMatcher: binutils.MatchAll( - binutils.MatchPath("**/*zulu*/**"), - binutils.MatchAny( - m.FileContentsVersionMatcher( - // [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL] - `(?m)\x00openjdk\x00java\x00(?P[0-9]+[.0-9]*)\x00(?P[0-9]+[^\x00]+)\x00`), - m.FileContentsVersionMatcher( - // arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL] - `(?m)\x00(?P[0-9]+[.0-9]*)\x00+(?P[0-9]+[^\x00]+)\x00+openjdk\x00java`), - ), - ), - Package: "zulu", - PURL: mustPURL("pkg:generic/azul/zulu@version"), - CPEs: singleCPE("cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), - }, { Class: "java-sdk-binary-ibm", EvidenceMatcher: binutils.MatchAll( diff --git a/syft/pkg/cataloger/binary/classifiers_java_test.go b/syft/pkg/cataloger/binary/classifiers_java_test.go new file mode 100644 index 000000000..3d642aab6 --- /dev/null +++ b/syft/pkg/cataloger/binary/classifiers_java_test.go @@ -0,0 +1,66 @@ +package binary + +import ( + "testing" + + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" +) + +func Test_JavaBinaryImage(t *testing.T) { + tests := []struct { + image string + expected []string + }{ + { + image: "image-java-binary", + expected: []string{ + "java @ 1.8.0-foreman_2022_09_22_15_30-b00 (/staged/positive/ibm/java)", + "jre @ 19.0.1+10-21 (/staged/positive/oracle-macos/java)", + "openjdk @ 1.8.0_352-b08 (/staged/positive/openjdk/java)", + "openjdk @ 11.0.17+8-LTS (/staged/positive/openjdk-lts/java)", + }, + }, + { + image: "image-java-zulu-8", + expected: []string{ + "zulu @ 1.8.0_462-b08 (/usr/lib/jvm/zulu8-ca-amd64/bin/jdb)", + }, + }, + { + image: "image-java-zulu-21", + expected: []string{ + "zulu @ 21.0.8+9-LTS (/usr/lib/jvm/zulu21-ca-amd64/bin/java)", + }, + }, + { + image: "image-java-ibm-8", + expected: []string{ + "java @ 1.8.0-foreman_2023_10_12_13_27-b00 (/opt/ibm/java/jre/bin/java)", + }, + }, + { + image: "image-java-ibm-jre-8", + expected: []string{ + "java @ 1.8.0-_2025_04_14_02_37-b00 (/opt/ibm/java/jre/bin/java)", + }, + }, + { + image: "image-java-ibm-sdk-8", + expected: []string{ + "java_sdk @ 1.8.0-foreman_2022_01_20_09_33-b00 (/opt/ibm/java/bin/jdb)", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.image, func(t *testing.T) { + c := NewClassifierCataloger(ClassifierCatalogerConfig{ + Classifiers: defaultJavaClassifiers(), + }) + pkgtest.NewCatalogTester(). + WithImageResolver(t, tt.image). + ExpectsPackageStrings(tt.expected). + TestCataloger(t, c) + }) + } +} diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index 3ed0334c5..605de343a 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -187,33 +187,6 @@ from-images: paths: - /usr/local/apache2/bin/httpd - - name: java-jre-ibm - version: 1.8.0_391 - images: - - ref: ibmjava:8@sha256:05ef6b0f754aa3a8cebcec36260a70c234a217b21240a998604f33459037bc08 - platform: linux/amd64 - paths: - - /opt/ibm/java/jre/bin/java - - /opt/ibm/java/jre/lib/amd64/jli/libjli.so - - - name: java-ibm-8-jre - version: 1.8.0_451 - images: - - ref: ibmjava:8-jre@sha256:3588cd1cc9b8646fe03b3b15210e69b1b520f1321f8518b69c0e7013d702fd23 - platform: linux/amd64 - paths: - - /opt/ibm/java/jre/bin/java - - /opt/ibm/java/jre/lib/amd64/jli/libjli.so - - - name: java-ibm-8-sdk-alpine - version: 1.8.0_321 - images: - - ref: ibmjava:8-sdk-alpine@sha256:4f8ad2029e78f7b91721745a77fc6011a7c0e09b9edeffb6b20b6ec34a6e63cd - platform: linux/amd64 - paths: - - /opt/ibm/java/bin/jdb - - /opt/ibm/java/lib/amd64/jli/libjli.so - - version: 10.6.15 images: - ref: mariadb:10.6.15@sha256:92d499d9e02e92dc55c8160ef4004aa07f2e835197b18864ed214ca441e0dcfc diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-java-binary/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-java-binary/Dockerfile new file mode 100644 index 000000000..4c04d42a2 --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/image-java-binary/Dockerfile @@ -0,0 +1 @@ +FROM anchore/test_images:syft_bin-cf22714@sha256:c27b02c6322180fd8a7a3097d2b430bfdf9ea52ecf136edf258458e82f2c6f21 diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-8/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-8/Dockerfile new file mode 100644 index 000000000..ae472ceec --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-8/Dockerfile @@ -0,0 +1,6 @@ +FROM ibmjava:8@sha256:05ef6b0f754aa3a8cebcec36260a70c234a217b21240a998604f33459037bc08 AS builder + +FROM scratch + +COPY --from=builder /opt/ibm/java/jre/bin/java /opt/ibm/java/jre/bin/ +COPY --from=builder /opt/ibm/java/jre/lib/amd64/jli/libjli.so /opt/ibm/java/jre/lib/amd64/jli/ diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-jre-8/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-jre-8/Dockerfile new file mode 100644 index 000000000..4f99d357e --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-jre-8/Dockerfile @@ -0,0 +1,6 @@ +FROM ibmjava:8-jre@sha256:3588cd1cc9b8646fe03b3b15210e69b1b520f1321f8518b69c0e7013d702fd23 AS builder + +FROM scratch + +COPY --from=builder /opt/ibm/java/jre/bin/java /opt/ibm/java/jre/bin/ +COPY --from=builder /opt/ibm/java/jre/lib/amd64/jli/libjli.so /opt/ibm/java/jre/lib/amd64/jli/ diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-sdk-8/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-sdk-8/Dockerfile new file mode 100644 index 000000000..bde055c7d --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/image-java-ibm-sdk-8/Dockerfile @@ -0,0 +1,6 @@ +FROM ibmjava:8-sdk-alpine@sha256:4f8ad2029e78f7b91721745a77fc6011a7c0e09b9edeffb6b20b6ec34a6e63cd AS builder + +FROM scratch + +COPY --from=builder /opt/ibm/java/bin/jdb /opt/ibm/java/bin/ +COPY --from=builder /opt/ibm/java/lib/amd64/jli/libjli.so /opt/ibm/java/lib/amd64/jli/ diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-21/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-21/Dockerfile new file mode 100644 index 000000000..7b887e777 --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-21/Dockerfile @@ -0,0 +1,5 @@ +FROM azul/zulu-openjdk:21-jre-headless@sha256:581ebc852fcd9b52a5979b9b90dbe7cca2736bc1ecf1b9bd08ec41212d6675a4 AS builder + +FROM scratch + +COPY --from=builder /usr/lib/jvm/zulu21-ca-amd64/bin/java /usr/lib/jvm/zulu21-ca-amd64/bin/ diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-8/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-8/Dockerfile new file mode 100644 index 000000000..09f50c15f --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/image-java-zulu-8/Dockerfile @@ -0,0 +1,5 @@ +FROM azul/zulu-openjdk:8-latest@sha256:7e3116bf36566e046b763b4a33f410f07f591bc84c391aae4f7891f5ecbb6764 AS builder + +FROM scratch + +COPY --from=builder /usr/lib/jvm/zulu8-ca-amd64/bin/jdb /usr/lib/jvm/zulu8-ca-amd64/bin/ diff --git a/syft/pkg/cataloger/internal/binutils/branching_matcher.go b/syft/pkg/cataloger/internal/binutils/branching_matcher.go index 54f4484ed..c18e433e1 100644 --- a/syft/pkg/cataloger/internal/binutils/branching_matcher.go +++ b/syft/pkg/cataloger/internal/binutils/branching_matcher.go @@ -31,7 +31,7 @@ func BranchingEvidenceMatcher(classifiers ...Classifier) EvidenceMatcher { if err != nil { return nil, err } - return rdr, nil + return &nonClosingUnionReader{rdr}, nil }, }) if len(pkgs) > 0 || err != nil { @@ -41,3 +41,11 @@ func BranchingEvidenceMatcher(classifiers ...Classifier) EvidenceMatcher { return nil, nil } } + +type nonClosingUnionReader struct { + unionreader.UnionReader +} + +func (c *nonClosingUnionReader) Close() error { + return nil +}