mirror of
https://github.com/anchore/syft.git
synced 2026-11-04 16:36:40 +01:00
Add JVM cataloger (#3217)
* add jvm cataloger Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * simplify version selection Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * CPEs from JVM cataloger should be declared Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * ensure package overlap is enabled for sensitive use cases Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * more permissive glob 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:
@@ -25,55 +25,102 @@ var (
|
||||
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 excludeBinaryByFileOwnershipOverlap(r, s.Artifacts.Packages) {
|
||||
s.Artifacts.Packages.Delete(r.To.ID())
|
||||
s.Relationships = RemoveRelationshipsByID(s.Relationships, r.To.ID())
|
||||
if idToRemove := excludeByFileOwnershipOverlap(r, s.Artifacts.Packages); idToRemove != "" {
|
||||
s.Artifacts.Packages.Delete(idToRemove)
|
||||
s.Relationships = RemoveRelationshipsByID(s.Relationships, idToRemove)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// excludeBinaryByFileOwnershipOverlap will remove packages from a collection given the following properties are true
|
||||
// 1) the relationship between packages is OwnershipByFileOverlap
|
||||
// 2) the parent is an "os" package
|
||||
// 3) the child is a synthetic package generated by the binary cataloger
|
||||
// 4) the package names are identical
|
||||
// This was implemented as a way to help resolve: https://github.com/anchore/syft/issues/931
|
||||
func excludeBinaryByFileOwnershipOverlap(r artifact.Relationship, c *pkg.Collection) bool {
|
||||
// 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 false
|
||||
return ""
|
||||
}
|
||||
|
||||
parent := c.Package(r.From.ID())
|
||||
if parent == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
parentInExclusion := slices.Contains(osCatalogerTypes, parent.Type)
|
||||
if !parentInExclusion {
|
||||
return false
|
||||
return ""
|
||||
}
|
||||
|
||||
child := c.Package(r.To.ID())
|
||||
if child == nil {
|
||||
return false
|
||||
return ""
|
||||
}
|
||||
|
||||
if slices.Contains(binaryCatalogerTypes, child.Type) {
|
||||
return true
|
||||
if idToRemove := identifyOverlappingOSRelationship(parent, child); idToRemove != "" {
|
||||
return idToRemove
|
||||
}
|
||||
|
||||
if idToRemove := identifyOverlappingJVMRelationship(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 false
|
||||
return ""
|
||||
}
|
||||
|
||||
childMetadataType := reflect.TypeOf(child.Metadata)
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
return slices.Contains(binaryMetadataTypes, childMetadataType.Name())
|
||||
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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user