mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
Infer the package type from ELF package notes (#3008)
* fix ELF package types to be honored Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * prefer OS packages over binary packages when there are duplicates Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
c816039e91
commit
573440b7cf
5 changed files with 62 additions and 8 deletions
|
@ -10,7 +10,8 @@ import (
|
|||
func TestMarinerDistroless(t *testing.T) {
|
||||
sbom, _ := catalogFixtureImage(t, "image-mariner-distroless", source.SquashedScope)
|
||||
|
||||
expectedPkgs := 12
|
||||
// 12 RPMs + 2 binaries with ELF package notes claiming to be RPMs
|
||||
expectedPkgs := 14
|
||||
actualPkgs := 0
|
||||
for range sbom.Artifacts.Packages.Enumerate(pkg.RpmPkg) {
|
||||
actualPkgs += 1
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package relationship
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"github.com/anchore/syft/internal/sbomsync"
|
||||
|
@ -21,6 +22,10 @@ var (
|
|||
binaryCatalogerTypes = []pkg.Type{
|
||||
pkg.BinaryPkg,
|
||||
}
|
||||
binaryMetadataTypes = []string{
|
||||
reflect.TypeOf(pkg.ELFBinaryPackageNoteJSONPayload{}).Name(),
|
||||
reflect.TypeOf(pkg.BinarySignature{}).Name(),
|
||||
}
|
||||
)
|
||||
|
||||
func ExcludeBinariesByFileOwnershipOverlap(accessor sbomsync.Accessor) {
|
||||
|
@ -60,5 +65,15 @@ func excludeBinaryByFileOwnershipOverlap(r artifact.Relationship, c *pkg.Collect
|
|||
return false
|
||||
}
|
||||
|
||||
return slices.Contains(binaryCatalogerTypes, child.Type)
|
||||
if slices.Contains(binaryCatalogerTypes, child.Type) {
|
||||
return true
|
||||
}
|
||||
|
||||
if child.Metadata == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
childMetadataType := reflect.TypeOf(child.Metadata)
|
||||
|
||||
return slices.Contains(binaryMetadataTypes, childMetadataType.Name())
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ func TestExclude(t *testing.T) {
|
|||
packageB := pkg.Package{Name: "package-a", Type: pkg.PythonPkg}
|
||||
packageC := pkg.Package{Name: "package-a", Type: pkg.BinaryPkg}
|
||||
packageD := pkg.Package{Name: "package-d", Type: pkg.BinaryPkg}
|
||||
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} {
|
||||
packageE := pkg.Package{Name: "package-e", Type: pkg.RpmPkg, Metadata: pkg.ELFBinaryPackageNoteJSONPayload{Type: "rpm"}}
|
||||
packageF := pkg.Package{Name: "package-f", Type: pkg.RpmPkg, Metadata: pkg.BinarySignature{}}
|
||||
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD, &packageE, &packageF} {
|
||||
p := p
|
||||
p.SetID()
|
||||
}
|
||||
|
@ -43,6 +45,26 @@ func TestExclude(t *testing.T) {
|
|||
packages: pkg.NewCollection(packageA, packageC),
|
||||
shouldExclude: true,
|
||||
},
|
||||
{
|
||||
name: "exclusions from os -> elf binary (as RPM)",
|
||||
relationship: artifact.Relationship{
|
||||
Type: artifact.OwnershipByFileOverlapRelationship,
|
||||
From: packageA,
|
||||
To: packageE,
|
||||
},
|
||||
packages: pkg.NewCollection(packageA, packageE),
|
||||
shouldExclude: true,
|
||||
},
|
||||
{
|
||||
name: "exclusions from os -> binary (masquerading as RPM)",
|
||||
relationship: artifact.Relationship{
|
||||
Type: artifact.OwnershipByFileOverlapRelationship,
|
||||
From: packageA,
|
||||
To: packageF,
|
||||
},
|
||||
packages: pkg.NewCollection(packageA, packageF),
|
||||
shouldExclude: true,
|
||||
},
|
||||
{
|
||||
name: "no exclusions from python -> binary",
|
||||
relationship: artifact.Relationship{
|
||||
|
|
|
@ -13,7 +13,7 @@ func newELFPackage(metadata elfBinaryPackageNotes, locations file.LocationSet) p
|
|||
Version: metadata.Version,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicense(metadata.License)),
|
||||
PURL: packageURL(metadata),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkgType(metadata.Type),
|
||||
Locations: locations,
|
||||
Metadata: metadata.ELFBinaryPackageNoteJSONPayload,
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ func packageURL(metadata elfBinaryPackageNotes) string {
|
|||
).ToString()
|
||||
}
|
||||
|
||||
const alpmType = "alpm"
|
||||
|
||||
func purlDistroType(ty string) string {
|
||||
switch ty {
|
||||
case "rpm":
|
||||
|
@ -75,8 +77,22 @@ func purlDistroType(ty string) string {
|
|||
return packageurl.TypeDebian
|
||||
case "apk":
|
||||
return packageurl.TypeAlpine
|
||||
case "alpm":
|
||||
return "alpm"
|
||||
case alpmType:
|
||||
return alpmType
|
||||
}
|
||||
return packageurl.TypeGeneric
|
||||
}
|
||||
|
||||
func pkgType(ty string) pkg.Type {
|
||||
switch ty {
|
||||
case "rpm":
|
||||
return pkg.RpmPkg
|
||||
case "deb":
|
||||
return pkg.DebPkg
|
||||
case "apk":
|
||||
return pkg.ApkPkg
|
||||
case alpmType:
|
||||
return pkg.AlpmPkg
|
||||
}
|
||||
return pkg.BinaryPkg
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
|||
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkg.RpmPkg,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "rpm",
|
||||
Architecture: "x86_64",
|
||||
|
@ -99,7 +99,7 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
|||
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkg.RpmPkg,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "rpm",
|
||||
Architecture: "arm",
|
||||
|
|
Loading…
Reference in a new issue