diff --git a/syft/pkg/cataloger/binary/capabilities.yaml b/syft/pkg/cataloger/binary/capabilities.yaml index 600207a5a..22a810cad 100644 --- a/syft/pkg/cataloger/binary/capabilities.yaml +++ b/syft/pkg/cataloger/binary/capabilities.yaml @@ -66,6 +66,16 @@ catalogers: cpes: - cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:* type: BinaryPkg + - method: glob + criteria: + - '**/julia' + packages: + - class: julia-binary + name: julia + purl: pkg:generic/julia + cpes: + - cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:* + type: BinaryPkg - method: glob criteria: - '**/helm' diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index a622d8172..56a3d9d63 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -2477,6 +2477,106 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("ingress-nginx-binary"), }, }, + { + logicalFixture: "julia/1.13.0-alpha2/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.13.0-alpha2", + Type: "binary", + PURL: "pkg:generic/julia@1.13.0-alpha2", + Locations: locations("libjulia-internal.so.1.13.0"), + Metadata: metadata("julia-binary"), + }, + }, + { + logicalFixture: "julia/1.12.6/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.12.6", + Type: "binary", + PURL: "pkg:generic/julia@1.12.6", + Locations: locations("libjulia-internal.so.1.12.6"), + Metadata: metadata("julia-binary"), + }, + }, + { + logicalFixture: "julia/1.11.9/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.11.9", + Type: "binary", + PURL: "pkg:generic/julia@1.11.9", + Locations: locations("libjulia-internal.so.1.11.9"), + Metadata: metadata("julia-binary"), + }, + }, + { + logicalFixture: "julia/1.10.11/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.10.11", + Type: "binary", + PURL: "pkg:generic/julia@1.10.11", + Locations: locations("libjulia-internal.so.1.10.11"), + Metadata: metadata("julia-binary"), + }, + }, + { + logicalFixture: "julia/1.9.0-alpha1/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.9.0-alpha1", + Type: "binary", + PURL: "pkg:generic/julia@1.9.0-alpha1", + Locations: locations("libjulia-internal.so.1.9"), + Metadata: metadata("julia-binary"), + }, + }, + { + logicalFixture: "julia/1.8.5/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.8.5", + Type: "binary", + PURL: "pkg:generic/julia@1.8.5", + Locations: locations("libjulia-internal.so.1.8"), + Metadata: metadata("julia-binary"), + }, + }, + { + // note: dynamic (non-snippet) test case + logicalFixture: "julia/1.5.4/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.5.4", + Type: "binary", + PURL: "pkg:generic/julia@1.5.4", + Locations: locations("julia", "libjulia.so.1.5"), + Metadata: pkg.BinarySignature{ + Matches: []pkg.ClassifierMatch{ + match("julia-binary", "julia"), + match("julia-binary", "libjulia.so.1.5"), + }, + }, + }, + }, + { + // note: dynamic (non-snippet) test case + logicalFixture: "julia/1.3.1/linux-amd64", + expected: pkg.Package{ + Name: "julia", + Version: "1.3.1", + Type: "binary", + PURL: "pkg:generic/julia@1.3.1", + Locations: locations("julia", "libjulia.so.1.3"), + Metadata: pkg.BinarySignature{ + Matches: []pkg.ClassifierMatch{ + match("julia-binary", "julia"), + match("julia-binary", "libjulia.so.1.3"), + }, + }, + }, + }, } for _, test := range tests { diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index aa9b00d2a..d76eca517 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -88,8 +88,43 @@ func DefaultClassifiers() []binutils.Classifier { { Class: "julia-binary", FileGlob: "**/libjulia-internal.so", - EvidenceMatcher: m.FileContentsVersionMatcher( - `(?m)__init__\x00(?P[0-9]+\.[0-9]+\.[0-9]+)\x00verify`), + EvidenceMatcher: binutils.MatchAny( + // �1.13.0-beta3[NUL]branch + // [NUL]GIT_VERSION_INFO[NUL]jl_image_unpack[NUL]1.13.0-alpha2[NUL]branch + // [NUL]GIT_VERSION_INFO[NUL]__init__[NUL]1.12.6[NUL]branch[NUL]commit + // [NUL]GIT_VERSION_INFO[NUL]__init__[NUL]verify_methods[NUL]1.11.9[NUL]branch[NUL]commit + // [NUL][NUL]__init__[NUL]1.10.11[NUL]verify_methods[NUL] + m.FileContentsVersionMatcher(`\x00__init__\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(branch|verify_methods)`), + m.FileContentsVersionMatcher(`(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00branch\x00`), + // [NUL]verify_methods[NUL]Task cannot be serialized[NUL]1.9.0-alpha1[NUL]BigInt[NUL] + m.FileContentsVersionMatcher(`\x00verify_methods\x00.{0,30}(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00BigInt`), + // unknown option `%s`[NUL]1.8.5[NUL]julia version %s + m.FileContentsVersionMatcher(`\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00julia version`), + ), + Package: "julia", + PURL: mustPURL("pkg:generic/julia@version"), + CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + }, + { + Class: "julia-binary", + FileGlob: "**/julia", + EvidenceMatcher: binutils.SharedLibraryLookup( + // libjulia.so.1 + // libjulia.so.0.6 + // libjulia.so + `^libjulia\.so(\.[0-9])?(\.[0-9])?$`, + binutils.MatchAny( + // unknown option `%s`[NUL]1.5.4[NUL]julia version %s + m.FileContentsVersionMatcher(`\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00julia version`), + // [NUL]#kw#[NUL]1.3.1[NUL]BigInt + // [NUL]#kw#[NUL]0.7.0-beta2[NUL]_require_dependencies + m.FileContentsVersionMatcher(`\x00#kw#\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(BigInt|_require_dependencies)`), + // [NUL]ObjectIdDict[NUL]0.6.4[NUL]jl_sysimg_cpu_target + m.FileContentsVersionMatcher(`\x00ObjectIdDict\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00jl_sysimg_cpu_target`), + // [NUL]require[NUL]0.4.6[NUL]core2 + m.FileContentsVersionMatcher(`\x00require\x00(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00core2`), + ), + ), Package: "julia", PURL: mustPURL("pkg:generic/julia@version"), CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), diff --git a/syft/pkg/cataloger/binary/internal/manager/internal/download_from_image.go b/syft/pkg/cataloger/binary/internal/manager/internal/download_from_image.go index 3b9801d4d..880916972 100644 --- a/syft/pkg/cataloger/binary/internal/manager/internal/download_from_image.go +++ b/syft/pkg/cataloger/binary/internal/manager/internal/download_from_image.go @@ -275,9 +275,15 @@ func copyBinaryFromContainer(containerName, containerPath, destinationPath, dige return err } - // ensure permissions are 600 for destination - if err := os.Chmod(destinationPath, 0600); err != nil { - return fmt.Errorf("unable to set permissions on file %q: %w", destinationPath, err) + // ensure permissions are 600 for destination (if it is not a symlink) + info, err := os.Lstat(destinationPath) + if err != nil { + return fmt.Errorf("unable to stat file %q: %w", destinationPath, err) + } + if info.Mode()&os.ModeSymlink == 0 { + if err := os.Chmod(destinationPath, 0600); err != nil { + return fmt.Errorf("unable to set permissions on file %q: %w", destinationPath, err) + } } // capture digest file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.10.11/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.10.11/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..9a3310cea --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.10.11/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.10.11 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.10.11/linux-amd64/libjulia-internal.so.1.10.11 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.10.11/linux-amd64/libjulia-internal.so.1.10.11 new file mode 100644 index 000000000..134e1d0ef Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.10.11/linux-amd64/libjulia-internal.so.1.10.11 differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.11.9/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.11.9/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..ac50092f7 --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.11.9/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.11.9 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.11.9/linux-amd64/libjulia-internal.so.1.11.9 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.11.9/linux-amd64/libjulia-internal.so.1.11.9 new file mode 100644 index 000000000..d3a46ef78 Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.11.9/linux-amd64/libjulia-internal.so.1.11.9 differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.12.6/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.12.6/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..e818e1dfa --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.12.6/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.12.6 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.12.6/linux-amd64/libjulia-internal.so.1.12.6 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.12.6/linux-amd64/libjulia-internal.so.1.12.6 new file mode 100644 index 000000000..8738add0d Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.12.6/linux-amd64/libjulia-internal.so.1.12.6 differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-alpha2/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-alpha2/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..7c3769bab --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-alpha2/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.13.0 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-alpha2/linux-amd64/libjulia-internal.so.1.13.0 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-alpha2/linux-amd64/libjulia-internal.so.1.13.0 new file mode 100644 index 000000000..f00de76f2 Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-alpha2/linux-amd64/libjulia-internal.so.1.13.0 differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-beta3/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-beta3/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..7c3769bab --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-beta3/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.13.0 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-beta3/linux-amd64/libjulia-internal.so.1.13.0 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-beta3/linux-amd64/libjulia-internal.so.1.13.0 new file mode 100644 index 000000000..54a837617 Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.13.0-beta3/linux-amd64/libjulia-internal.so.1.13.0 differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.8.5/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.8.5/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..c0bfe7487 --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.8.5/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.8 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.8.5/linux-amd64/libjulia-internal.so.1.8 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.8.5/linux-amd64/libjulia-internal.so.1.8 new file mode 100644 index 000000000..7c82096ec Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.8.5/linux-amd64/libjulia-internal.so.1.8 differ diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.9.0-alpha1/linux-amd64/libjulia-internal.so b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.9.0-alpha1/linux-amd64/libjulia-internal.so new file mode 120000 index 000000000..67ef60061 --- /dev/null +++ b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.9.0-alpha1/linux-amd64/libjulia-internal.so @@ -0,0 +1 @@ +libjulia-internal.so.1.9 \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.9.0-alpha1/linux-amd64/libjulia-internal.so.1.9 b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.9.0-alpha1/linux-amd64/libjulia-internal.so.1.9 new file mode 100644 index 000000000..4757759c3 Binary files /dev/null and b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/julia/1.9.0-alpha1/linux-amd64/libjulia-internal.so.1.9 differ diff --git a/syft/pkg/cataloger/binary/testdata/config.yaml b/syft/pkg/cataloger/binary/testdata/config.yaml index 43ddfec02..4f933c25c 100644 --- a/syft/pkg/cataloger/binary/testdata/config.yaml +++ b/syft/pkg/cataloger/binary/testdata/config.yaml @@ -1524,3 +1524,86 @@ from-images: paths: - /nginx-ingress-controller + - name: julia + version: 1.13.0-beta3 + images: + - ref: library/julia:1.13.0-beta3@sha256:3b36013b071d9abc9bdedb66a4230a9445bc692aa2c49f85852b94e81c7f0a74 + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.13.0 + + - name: julia + version: 1.13.0-alpha2 + images: + - ref: library/julia:1.13.0-alpha2@sha256:f1b1cd24979025371be317353d0d9071e9b549583d2b13783cbafd40b8d4e319 + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.13.0 + + - name: julia + version: 1.12.6 + images: + - ref: library/julia:1.12.6@sha256:54d6a3f40bbd76021e6ca8fab2dd2af08cc5388b078223d3040eaf3567b4ccd3 + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.12.6 + + - name: julia + version: 1.11.9 + images: + - ref: library/julia:1.11.9@sha256:18e83baa9277c2ac94bef267d585634760b5adf9bc7343480161c7b09034b452 + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.11.9 + + - name: julia + version: 1.10.11 + images: + - ref: library/julia:1.10.11@sha256:2f27b44f3ecda0f941c1b475b8967fa933fbf52b5f877f69bfe4df959c56df66 + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.10.11 + + - name: julia + version: 1.9.0-alpha1 + images: + - ref: library/julia:1.9.0-alpha1@sha256:fb932603485d7cea435e85c073c04bdf4d0b90232c03013585aa0f65c8216111 + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.9 + + - name: julia + version: 1.8.5 + images: + - ref: library/julia:1.8.5@sha256:5edccd0ca0b5f00d78beca0bd8217d65b2c24ef051ad07e2b08ed67224ff905a + platform: linux/amd64 + paths: + - /usr/local/julia/lib/julia/libjulia-internal.so + - /usr/local/julia/lib/julia/libjulia-internal.so.1.8 + + - name: julia + version: 1.5.4 + images: + - ref: library/julia:1.5.4@sha256:39c3f721aa5ede195965e7f20575b1ee5949bdd2b42204e227d98114bcc94b83 + platform: linux/amd64 + paths: + - /usr/local/julia/bin/julia + - /usr/local/julia/lib/libjulia.so.1 + - /usr/local/julia/lib/libjulia.so.1.5 + + - name: julia + version: 1.3.1 + images: + - ref: library/julia:1.3.1@sha256:a14f56f9f2ed44559d9f435cc346ede09a7d61afcbac61ba037acd2b39b56171 + platform: linux/amd64 + paths: + - /usr/local/julia/bin/julia + - /usr/local/julia/lib/libjulia.so.1 + - /usr/local/julia/lib/libjulia.so.1.3 +