From f92ea096856c7c262b05bd4d31c62689ebafac82 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Thu, 30 May 2024 11:36:57 +0600 Subject: [PATCH] fix(sbom): fix panic for `convert` mode when scanning json file derived from sbom file (#6808) --- pkg/sbom/io/encode.go | 11 ++- pkg/sbom/io/encode_test.go | 154 +++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) diff --git a/pkg/sbom/io/encode.go b/pkg/sbom/io/encode.go index db9052f033dd..9672f1648dc6 100644 --- a/pkg/sbom/io/encode.go +++ b/pkg/sbom/io/encode.go @@ -83,8 +83,15 @@ func (e *Encoder) rootComponent(r types.Report) (*core.Component, error) { root.Type = core.TypeFilesystem case artifact.TypeRepository: root.Type = core.TypeRepository - case artifact.TypeCycloneDX: - return r.BOM.Root(), nil + case artifact.TypeCycloneDX, artifact.TypeSPDX: + // When we scan SBOM file + if r.BOM != nil { + return r.BOM.Root(), nil + } + // When we scan a `json` file (meaning a file in `json` format) which was created from the SBOM file. + // e.g. for use in `convert` mode. + // See https://github.com/aquasecurity/trivy/issues/6780 + root.Type = core.TypeFilesystem } if r.Metadata.Size != 0 { diff --git a/pkg/sbom/io/encode_test.go b/pkg/sbom/io/encode_test.go index c6cc450da832..d165b64c3e80 100644 --- a/pkg/sbom/io/encode_test.go +++ b/pkg/sbom/io/encode_test.go @@ -535,6 +535,97 @@ func TestEncoder_Encode(t *testing.T) { }, wantVulns: make(map[uuid.UUID][]core.Vulnerability), }, + { + name: "SBOM file", + report: types.Report{ + SchemaVersion: 2, + ArtifactName: "report.cdx.json", + ArtifactType: artifact.TypeCycloneDX, + Results: []types.Result{ + { + Target: "Java", + Type: ftypes.Jar, + Class: types.ClassLangPkg, + Packages: []ftypes.Package{ + { + ID: "org.apache.logging.log4j:log4j-core:2.23.1", + Name: "org.apache.logging.log4j:log4j-core", + Version: "2.23.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.logging.log4j", + Name: "log4j-core", + Version: "2.23.1", + }, + }, + FilePath: "log4j-core-2.23.1.jar", + }, + }, + }, + }, + BOM: newTestBOM(t), + }, + wantComponents: map[uuid.UUID]*core.Component{ + uuid.MustParse("2ff14136-e09f-4df9-80ea-000000000001"): appComponent, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): libComponent, + }, + wantRels: map[uuid.UUID][]core.Relationship{ + uuid.MustParse("2ff14136-e09f-4df9-80ea-000000000001"): { + { + Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"), + Type: core.RelationshipContains, + }, + }, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): nil, + }, + wantVulns: make(map[uuid.UUID][]core.Vulnerability), + }, + { + name: "json file created from SBOM file (BOM is empty)", + report: types.Report{ + SchemaVersion: 2, + ArtifactName: "report.cdx.json", + ArtifactType: artifact.TypeCycloneDX, + Results: []types.Result{ + { + Target: "Java", + Type: ftypes.Jar, + Class: types.ClassLangPkg, + Packages: []ftypes.Package{ + { + ID: "org.apache.logging.log4j:log4j-core:2.23.1", + Name: "org.apache.logging.log4j:log4j-core", + Version: "2.23.1", + Identifier: ftypes.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.logging.log4j", + Name: "log4j-core", + Version: "2.23.1", + }, + }, + FilePath: "log4j-core-2.23.1.jar", + }, + }, + }, + }, + }, + wantComponents: map[uuid.UUID]*core.Component{ + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): fsComponent, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): libComponent, + }, + wantRels: map[uuid.UUID][]core.Relationship{ + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): { + { + Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"), + Type: core.RelationshipContains, + }, + }, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): nil, + }, + wantVulns: make(map[uuid.UUID][]core.Vulnerability), + }, { name: "invalid digest", report: types.Report{ @@ -580,3 +671,66 @@ func TestEncoder_Encode(t *testing.T) { }) } } + +var ( + appComponent = &core.Component{ + Root: true, + Type: core.TypeApplication, + Name: "log4j-core-2.23.1.jar", + } + fsComponent = &core.Component{ + Root: true, + Type: core.TypeFilesystem, + Name: "report.cdx.json", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "3ff14136-e09f-4df9-80ea-000000000001", + }, + Properties: core.Properties{ + { + Name: "SchemaVersion", + Value: "2", + }, + }, + } + libComponent = &core.Component{ + Type: core.TypeLibrary, + Name: "log4j-core", + Group: "org.apache.logging.log4j", + Version: "2.23.1", + PkgIdentifier: ftypes.PkgIdentifier{ + BOMRef: "pkg:maven/org.apache.logging.log4j/log4j-core@2.23.1", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.logging.log4j", + Name: "log4j-core", + Version: "2.23.1", + }, + }, + Files: []core.File{ + { + Path: "log4j-core-2.23.1.jar", + }, + }, + Properties: core.Properties{ + { + Name: "FilePath", + Value: "log4j-core-2.23.1.jar", + }, + { + Name: "PkgID", + Value: "org.apache.logging.log4j:log4j-core:2.23.1", + }, + { + Name: "PkgType", + Value: "jar", + }, + }, + } +) + +func newTestBOM(t *testing.T) *core.BOM { + uuid.SetFakeUUID(t, "2ff14136-e09f-4df9-80ea-%012d") + bom := core.NewBOM(core.Options{}) + bom.AddComponent(appComponent) + return bom +}