fix: improve julia classifier to find shared libs and beta versions (#4945)

Signed-off-by: witchcraze <witchcraze@gmail.com>
This commit is contained in:
witchcraze 2026-05-30 01:05:46 +09:00 committed by GitHub
parent e8c6b7151e
commit 4e86715c1a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 246 additions and 5 deletions

View File

@ -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'

View File

@ -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 {

View File

@ -88,8 +88,43 @@ func DefaultClassifiers() []binutils.Classifier {
{
Class: "julia-binary",
FileGlob: "**/libjulia-internal.so",
EvidenceMatcher: m.FileContentsVersionMatcher(
`(?m)__init__\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00verify`),
EvidenceMatcher: binutils.MatchAny(
// <20>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<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00(branch|verify_methods)`),
m.FileContentsVersionMatcher(`(?P<version>[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<version>[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<version>[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<version>[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<version>[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<version>[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<version>[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),

View File

@ -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

View File

@ -0,0 +1 @@
libjulia-internal.so.1.10.11

View File

@ -0,0 +1 @@
libjulia-internal.so.1.11.9

View File

@ -0,0 +1 @@
libjulia-internal.so.1.12.6

View File

@ -0,0 +1 @@
libjulia-internal.so.1.13.0

View File

@ -0,0 +1 @@
libjulia-internal.so.1.13.0

View File

@ -0,0 +1 @@
libjulia-internal.so.1.8

View File

@ -0,0 +1 @@
libjulia-internal.so.1.9

View File

@ -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