fix: Exclude binary packages that have overlap by file ownership relationship (#1024)

This commit is contained in:
Keith Zantow 2022-12-12 15:59:47 -05:00 committed by GitHub
parent 2ace4c0b11
commit 2c94031e1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 104 additions and 3 deletions

3
.gitignore vendored
View file

@ -19,6 +19,9 @@ CHANGELOG.md
*.tmp
coverage.txt
# OS files
.DS_Store
# Binaries for programs and plugins
*.exe
*.exe~

View file

@ -6,6 +6,7 @@ import (
"github.com/anchore/grype/internal"
"github.com/anchore/grype/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/common/cpe"
"github.com/anchore/syft/syft/source"
@ -88,6 +89,25 @@ func (p Package) String() string {
return fmt.Sprintf("Pkg(type=%s, name=%s, version=%s, upstreams=%d)", p.Type, p.Name, p.Version, len(p.Upstreams))
}
func RemoveBinaryPackagesByOverlap(catalog *pkg.Catalog, relationships []artifact.Relationship) *pkg.Catalog {
byOverlap := map[artifact.ID]artifact.Identifiable{}
for _, r := range relationships {
if r.Type == artifact.OwnershipByFileOverlapRelationship {
byOverlap[r.To.ID()] = r.To
}
}
out := pkg.NewCatalog()
for p := range catalog.Enumerate() {
if _, ok := byOverlap[p.ID()]; p.Type == pkg.BinaryPkg && ok {
continue
}
out.Add(p)
}
return out
}
func dataFromPkg(p pkg.Package) (MetadataType, interface{}, []UpstreamPackage) {
var metadata interface{}
var upstreams []UpstreamPackage

View file

@ -7,6 +7,7 @@ import (
"github.com/scylladb/go-set/strset"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
syftFile "github.com/anchore/syft/syft/file"
syftPkg "github.com/anchore/syft/syft/pkg"
@ -486,3 +487,74 @@ func Test_getNameAndELVersion(t *testing.T) {
func intRef(i int) *int {
return &i
}
func Test_RemoveBinaryPackagesByOverlap(t *testing.T) {
tests := []struct {
name string
sbom catalogRelationships
expectedPackages []string
}{
{
name: "includes all packages without overlap",
sbom: catalogWithBinaryOverlaps([]string{"go"}, []string{}),
expectedPackages: []string{"go"},
},
{
name: "excludes single package by overlap",
sbom: catalogWithBinaryOverlaps([]string{"go", "node"}, []string{"node"}),
expectedPackages: []string{"go"},
},
{
name: "excludes multiple package by overlap",
sbom: catalogWithBinaryOverlaps([]string{"go", "node", "python", "george"}, []string{"node", "george"}),
expectedPackages: []string{"go", "python"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
catalog := RemoveBinaryPackagesByOverlap(test.sbom.catalog, test.sbom.relationships)
pkgs := FromCatalog(catalog, SynthesisConfig{})
var pkgNames []string
for _, p := range pkgs {
pkgNames = append(pkgNames, p.Name)
}
assert.EqualValues(t, test.expectedPackages, pkgNames)
})
}
}
type catalogRelationships struct {
catalog *syftPkg.Catalog
relationships []artifact.Relationship
}
func catalogWithBinaryOverlaps(packages []string, overlaps []string) catalogRelationships {
var pkgs []syftPkg.Package
var relationships []artifact.Relationship
for _, name := range packages {
p := syftPkg.Package{
Name: name,
Type: syftPkg.BinaryPkg,
}
p.SetID()
for _, overlap := range overlaps {
if overlap == name {
relationships = append(relationships, artifact.Relationship{
From: p,
To: p,
Type: artifact.OwnershipByFileOverlapRelationship,
})
}
}
pkgs = append(pkgs, p)
}
catalog := syftPkg.NewCatalog(pkgs...)
return catalogRelationships{
catalog: catalog,
relationships: relationships,
}
}

View file

@ -21,11 +21,13 @@ func syftProvider(userInput string, config ProviderConfig) ([]Package, Context,
}
defer cleanup()
catalog, _, theDistro, err := syft.CatalogPackages(src, config.CatalogingOptions)
catalog, relationships, theDistro, err := syft.CatalogPackages(src, config.CatalogingOptions)
if err != nil {
return nil, Context{}, err
}
catalog = RemoveBinaryPackagesByOverlap(catalog, relationships)
return FromCatalog(catalog, config.SynthesisConfig), Context{
Source: &src.Metadata,
Distro: theDistro,

View file

@ -41,7 +41,10 @@ func syftSBOMProvider(userInput string, config ProviderConfig) ([]Package, Conte
return nil, Context{}, err
}
return FromCatalog(s.Artifacts.PackageCatalog, config.SynthesisConfig), Context{
catalog := s.Artifacts.PackageCatalog
catalog = RemoveBinaryPackagesByOverlap(catalog, s.Relationships)
return FromCatalog(catalog, config.SynthesisConfig), Context{
Source: &s.Source,
Distro: s.Artifacts.LinuxDistribution,
}, nil

View file

@ -0,0 +1 @@
3.10.7

@ -1 +1 @@
Subproject commit 6ca252c622bc67e7670fe5333464400ceafbe64d
Subproject commit c2876a52c5f876bdf05439b46541f8a7a67b1f7c