mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
* prototype: start bitnami cataloger Bitnami images have spdx SBOMs at predictable paths, and Syft could more accurately identify the software in these images by scanning those SBOMs. Start work on this by forking the sbom-cataloger as a new bitnami-cataloger. Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * wire up bitnami cataloger to run on images by default Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * feat: add support for Bitnami cataloguer Signed-off-by: juan131 <jariza@vmware.com> * feat: use a better SPDX sample for unit tests Signed-off-by: juan131 <jariza@vmware.com> * bugfix: only report bitnami pkgs Signed-off-by: juan131 <jariza@vmware.com> * feat: adapt JSON schema, spdxutil and packagemetadata Signed-off-by: juan131 <jariza@vmware.com> * bugfix: integration tests Signed-off-by: juan131 <jariza@vmware.com> * feat: implement FileOwner interface Signed-off-by: juan131 <jariza@vmware.com> * bugfix: update json schema Signed-off-by: juan131 <jariza@vmware.com> * [wip] add bitnami owned files and fix binary package ownership filtering Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * feat: obtain bitnami pkg files based on SPDX relationships tree Signed-off-by: juan131 <jariza@vmware.com> * preserve type switches Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * rename bitnami entry metadata type Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * restrict find main pkg logic Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add missing graalvm source info Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bugfix: integration tests Signed-off-by: juan131 <jariza@vmware.com> * bugfix: mod tidy Signed-off-by: juan131 <jariza@vmware.com> --------- Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> Signed-off-by: juan131 <jariza@vmware.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Will Murphy <willmurphyscode@users.noreply.github.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
155 lines
3.8 KiB
Go
155 lines
3.8 KiB
Go
package relationship
|
|
|
|
import (
|
|
"reflect"
|
|
"slices"
|
|
|
|
"github.com/anchore/syft/internal/sbomsync"
|
|
"github.com/anchore/syft/syft/artifact"
|
|
"github.com/anchore/syft/syft/pkg"
|
|
"github.com/anchore/syft/syft/sbom"
|
|
)
|
|
|
|
var (
|
|
osCatalogerTypes = []pkg.Type{
|
|
pkg.AlpmPkg,
|
|
pkg.ApkPkg,
|
|
pkg.DebPkg,
|
|
pkg.NixPkg,
|
|
pkg.PortagePkg,
|
|
pkg.RpmPkg,
|
|
}
|
|
binaryCatalogerTypes = []pkg.Type{
|
|
pkg.BinaryPkg,
|
|
}
|
|
bitnamiCatalogerTypes = []pkg.Type{
|
|
pkg.BitnamiPkg,
|
|
}
|
|
binaryMetadataTypes = []string{
|
|
reflect.TypeOf(pkg.ELFBinaryPackageNoteJSONPayload{}).Name(),
|
|
reflect.TypeOf(pkg.BinarySignature{}).Name(),
|
|
reflect.TypeOf(pkg.JavaVMInstallation{}).Name(),
|
|
}
|
|
)
|
|
|
|
func ExcludeBinariesByFileOwnershipOverlap(accessor sbomsync.Accessor) {
|
|
accessor.WriteToSBOM(func(s *sbom.SBOM) {
|
|
for _, r := range s.Relationships {
|
|
if idToRemove := excludeByFileOwnershipOverlap(r, s.Artifacts.Packages); idToRemove != "" {
|
|
s.Artifacts.Packages.Delete(idToRemove)
|
|
s.Relationships = RemoveRelationshipsByID(s.Relationships, idToRemove)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// excludeByFileOwnershipOverlap will remove packages that should be overridden by a more authoritative package,
|
|
// such as an OS package or a package from a cataloger with more specific information being raised up.
|
|
func excludeByFileOwnershipOverlap(r artifact.Relationship, c *pkg.Collection) artifact.ID {
|
|
if artifact.OwnershipByFileOverlapRelationship != r.Type {
|
|
return ""
|
|
}
|
|
|
|
parent := c.Package(r.From.ID())
|
|
if parent == nil {
|
|
return ""
|
|
}
|
|
|
|
child := c.Package(r.To.ID())
|
|
if child == nil {
|
|
return ""
|
|
}
|
|
|
|
if idToRemove := identifyOverlappingOSRelationship(parent, child); idToRemove != "" {
|
|
return idToRemove
|
|
}
|
|
|
|
if idToRemove := identifyOverlappingJVMRelationship(parent, child); idToRemove != "" {
|
|
return idToRemove
|
|
}
|
|
|
|
if idToRemove := identifyOverlappingBitnamiRelationship(parent, child); idToRemove != "" {
|
|
return idToRemove
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// identifyOverlappingJVMRelationship indicates the package to remove if this is a binary -> binary pkg relationship
|
|
// with a java binary signature package and a more authoritative JVM release package.
|
|
func identifyOverlappingJVMRelationship(parent *pkg.Package, child *pkg.Package) artifact.ID {
|
|
if !slices.Contains(binaryCatalogerTypes, parent.Type) {
|
|
return ""
|
|
}
|
|
|
|
if !slices.Contains(binaryCatalogerTypes, child.Type) {
|
|
return ""
|
|
}
|
|
|
|
if child.Metadata == nil {
|
|
return ""
|
|
}
|
|
|
|
var (
|
|
foundJVM bool
|
|
idToRemove artifact.ID
|
|
)
|
|
for _, p := range []*pkg.Package{parent, child} {
|
|
switch p.Metadata.(type) {
|
|
case pkg.JavaVMInstallation:
|
|
foundJVM = true
|
|
default:
|
|
idToRemove = p.ID()
|
|
}
|
|
}
|
|
|
|
if foundJVM {
|
|
return idToRemove
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// identifyOverlappingOSRelationship indicates the package ID to remove if this is an OS pkg -> bin pkg relationship.
|
|
// This was implemented as a way to help resolve: https://github.com/anchore/syft/issues/931
|
|
func identifyOverlappingOSRelationship(parent *pkg.Package, child *pkg.Package) artifact.ID {
|
|
if !slices.Contains(osCatalogerTypes, parent.Type) {
|
|
return ""
|
|
}
|
|
|
|
if slices.Contains(binaryCatalogerTypes, child.Type) {
|
|
return child.ID()
|
|
}
|
|
|
|
if child.Metadata == nil {
|
|
return ""
|
|
}
|
|
|
|
if !slices.Contains(binaryMetadataTypes, reflect.TypeOf(child.Metadata).Name()) {
|
|
return ""
|
|
}
|
|
|
|
return child.ID()
|
|
}
|
|
|
|
// identifyOverlappingBitnamiRelationship indicates the package ID to remove if this is a Bitnami pkg -> bin pkg relationship.
|
|
func identifyOverlappingBitnamiRelationship(parent *pkg.Package, child *pkg.Package) artifact.ID {
|
|
if !slices.Contains(bitnamiCatalogerTypes, parent.Type) {
|
|
return ""
|
|
}
|
|
|
|
if slices.Contains(binaryCatalogerTypes, child.Type) {
|
|
return child.ID()
|
|
}
|
|
|
|
if child.Metadata == nil {
|
|
return ""
|
|
}
|
|
|
|
if !slices.Contains(binaryMetadataTypes, reflect.TypeOf(child.Metadata).Name()) {
|
|
return ""
|
|
}
|
|
|
|
return child.ID()
|
|
}
|