Skip to content

Commit

Permalink
Merge pull request #993 from jonjohnsonjr/idb-to-sbom
Browse files Browse the repository at this point in the history
  • Loading branch information
imjasonh authored Dec 19, 2023
2 parents ce1f1d5 + 8ac4731 commit 7fb5de8
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 62 deletions.
4 changes: 2 additions & 2 deletions internal/cli/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ func TestPublish(t *testing.T) {
// We also want to check the children SBOMs because the index SBOM does not have
// references to the children SBOMs, just the children!
wantBoms := []string{
"sha256:bef40bcaa24ff513c1add5e0133a663519081ed5fd770a67609089ebb1b4a5a3",
"sha256:c400175e8fb4d7b3e2eb0442b7991716b3f6a770539f5e0f9d47e52a426e5431",
"sha256:1659428b4c619a57536ad62e473d46adbf9ca51eb8c765a9e835e6d1bddf8bcb",
"sha256:7126743a21e6bc7d81a72bb7570b0b951190eec361c50980592eacd177fd46d5",
}

for i, m := range im.Manifests {
Expand Down
19 changes: 0 additions & 19 deletions internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,6 @@
"SPDXRef-Package-sha256-7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4"
],
"files": [
{
"SPDXID": "SPDXRef-File--etc-os-release",
"fileName": "etc/os-release",
"licenseConcluded": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA1",
"checksumValue": "2a1171b49b2e3d59abad728c7b0480736ff792eb"
},
{
"algorithm": "SHA256",
"checksumValue": "1877864cb20a2a48b27fbae1dd33d90918a56c7e24e503976d0ceb3ab5c9eecd"
},
{
"algorithm": "SHA512",
"checksumValue": "2b2935e9103b1755bf0e4028528accd9f082548180e9e70d9a15383005603ce314ca89c8280a98dc9cc429c6bfe3596c0c6faaa7f6dc9a4d195ce3f560014876"
}
]
},
{
"SPDXID": "SPDXRef-File--etc-os-release",
"fileName": "etc/os-release",
Expand Down
19 changes: 0 additions & 19 deletions internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,6 @@
"SPDXRef-Package-sha256-e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926"
],
"files": [
{
"SPDXID": "SPDXRef-File--etc-os-release",
"fileName": "etc/os-release",
"licenseConcluded": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA1",
"checksumValue": "2a1171b49b2e3d59abad728c7b0480736ff792eb"
},
{
"algorithm": "SHA256",
"checksumValue": "1877864cb20a2a48b27fbae1dd33d90918a56c7e24e503976d0ceb3ab5c9eecd"
},
{
"algorithm": "SHA512",
"checksumValue": "2b2935e9103b1755bf0e4028528accd9f082548180e9e70d9a15383005603ce314ca89c8280a98dc9cc429c6bfe3596c0c6faaa7f6dc9a4d195ce3f560014876"
}
]
},
{
"SPDXID": "SPDXRef-File--etc-os-release",
"fileName": "etc/os-release",
Expand Down
3 changes: 2 additions & 1 deletion pkg/build/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,11 @@ func (bc *Context) GenerateImageSBOM(ctx context.Context, arch types.Architectur
s.OS.ID = info.ID
s.OS.Version = info.VersionID

pkgs, err := sbom.ReadPackageIndex(bc.fs)
pkgs, err := bc.apk.GetInstalled()
if err != nil {
return nil, fmt.Errorf("reading apk package index: %w", err)
}

s.Packages = pkgs

// Get the image digest
Expand Down
44 changes: 35 additions & 9 deletions pkg/sbom/generator/spdx/spdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (sx *SPDX) Generate(opts *options.Options, path string) error {
})

// Check to see if the apk contains an sbom describing itself
if err := sx.ProcessInternalApkSBOM(opts, doc, &p); err != nil {
if err := sx.ProcessInternalApkSBOM(opts, doc, &p, pkg); err != nil {
return fmt.Errorf("parsing internal apk SBOM: %w", err)
}
}
Expand Down Expand Up @@ -209,7 +209,7 @@ func locateApkSBOM(fsys apkfs.FullFS, p *Package) (string, error) {
return "", nil
}

func (sx *SPDX) ProcessInternalApkSBOM(opts *options.Options, doc *Document, p *Package) error {
func (sx *SPDX) ProcessInternalApkSBOM(opts *options.Options, doc *Document, p *Package, ipkg *apk.InstalledPackage) error {
// Check if apk installed an SBOM
path, err := locateApkSBOM(sx.fs, p)
if err != nil {
Expand Down Expand Up @@ -256,7 +256,7 @@ func (sx *SPDX) ProcessInternalApkSBOM(opts *options.Options, doc *Document, p *
todo[id] = struct{}{}
}

if err := copySBOMElements(internalDoc, doc, todo); err != nil {
if err := copySBOMElements(internalDoc, doc, todo, ipkg); err != nil {
return fmt.Errorf("copying element: %w", err)
}

Expand All @@ -275,7 +275,7 @@ func (sx *SPDX) ProcessInternalApkSBOM(opts *options.Options, doc *Document, p *
return nil
}

func copySBOMElements(sourceDoc, targetDoc *Document, todo map[string]struct{}) error {
func copySBOMElements(sourceDoc, targetDoc *Document, todo map[string]struct{}, ipkg *apk.InstalledPackage) error {
// Walk the graph looking for things to copy.
// Loop until we don't find any new todos.
for prev, next := 0, len(todo); next != prev; prev, next = next, len(todo) {
Expand All @@ -286,6 +286,25 @@ func copySBOMElements(sourceDoc, targetDoc *Document, todo map[string]struct{})
}
}

// The APK SBOMs we are copying Files from may have duplicate file entries.
//
// A file can be overwritten if:
// 1. one package replaces another package
// 2. the packages are in the same origin
//
// Files with the same checksum are also skipped on install since they don't conflict.
//
// We need to reconcile these files that were overwritten or omitted to avoid having
// conflicting entries (different checksums) for the same file in our image SBOM.
// To do this, we consult /lib/apk/db/installed to know which package's file "won".
// Here, we create a set of the files that are owned by this package and only include
//
// those when copying from sourceDoc.Files.
ownedFiles := map[string]struct{}{}
for _, hdr := range ipkg.Files {
ownedFiles[hdr.Name] = struct{}{}
}

// Now copy everything over.
done := make(map[string]struct{}, len(todo))

Expand All @@ -297,12 +316,19 @@ func copySBOMElements(sourceDoc, targetDoc *Document, todo map[string]struct{})
}

for _, f := range sourceDoc.Files {
if _, ok := todo[f.ID]; ok {
f.Name = strings.TrimPrefix(f.Name, "/") // Strip leading slashes, which SPDX doesn't like.
if _, ok := todo[f.ID]; !ok {
continue
}

targetDoc.Files = append(targetDoc.Files, f)
done[f.ID] = struct{}{}
done[f.ID] = struct{}{}

if _, ok := ownedFiles[f.Name]; !ok {
continue
}

f.Name = strings.TrimPrefix(f.Name, "/") // Strip leading slashes, which SPDX doesn't like.

targetDoc.Files = append(targetDoc.Files, f)
}

for _, r := range sourceDoc.Relationships {
Expand Down Expand Up @@ -390,7 +416,7 @@ func (sx *SPDX) imagePackage(opts *options.Options) (p *Package) {
}

// apkPackage returns a SPDX package describing an apk
func (sx *SPDX) apkPackage(opts *options.Options, pkg *apk.Package) Package {
func (sx *SPDX) apkPackage(opts *options.Options, pkg *apk.InstalledPackage) Package {
return Package{
ID: stringToIdentifier(fmt.Sprintf(
"SPDXRef-Package-%s-%s", pkg.Name, pkg.Version,
Expand Down
24 changes: 13 additions & 11 deletions pkg/sbom/generator/spdx/spdx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,20 @@ var testOpts = &options.Options{
Version: "3.0",
},
FileName: "sbom",
Packages: []*apk.Package{
Packages: []*apk.InstalledPackage{
{
Name: "musl",
Version: "1.2.2-r7",
Arch: "x86_64",
Description: "the musl c library (libc) implementation",
License: "MIT",
Origin: "musl",
Maintainer: "Pkg Author <[email protected]>",
Checksum: []byte{
0xd, 0xe6, 0xf4, 0x8c, 0xdc, 0xad, 0x92, 0xb8, 0xcf, 0x5b,
0x83, 0x7f, 0x78, 0xa2, 0xd9, 0xe3, 0x70, 0x70, 0x3a, 0x5c,
Package: apk.Package{
Name: "musl",
Version: "1.2.2-r7",
Arch: "x86_64",
Description: "the musl c library (libc) implementation",
License: "MIT",
Origin: "musl",
Maintainer: "Pkg Author <[email protected]>",
Checksum: []byte{
0xd, 0xe6, 0xf4, 0x8c, 0xdc, 0xad, 0x92, 0xb8, 0xcf, 0x5b,
0x83, 0x7f, 0x78, 0xa2, 0xd9, 0xe3, 0x70, 0x70, 0x3a, 0x5c,
},
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/sbom/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type Options struct {
Formats []string

// Packages is alist of packages which will be listed in the SBOM
Packages []*apk.Package
Packages []*apk.InstalledPackage
}

type PurlQualifiers map[string]string
Expand Down

0 comments on commit 7fb5de8

Please sign in to comment.