github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/internal/relationship/exclude_binaries_by_file_ownership_overlap.go (about)

     1  package relationship
     2  
     3  import (
     4  	"slices"
     5  
     6  	"github.com/anchore/syft/internal/sbomsync"
     7  	"github.com/anchore/syft/syft/artifact"
     8  	"github.com/anchore/syft/syft/pkg"
     9  	"github.com/anchore/syft/syft/sbom"
    10  )
    11  
    12  var (
    13  	osCatalogerTypes = []pkg.Type{
    14  		pkg.AlpmPkg,
    15  		pkg.ApkPkg,
    16  		pkg.DebPkg,
    17  		pkg.NixPkg,
    18  		pkg.PortagePkg,
    19  		pkg.RpmPkg,
    20  	}
    21  	binaryCatalogerTypes = []pkg.Type{
    22  		pkg.BinaryPkg,
    23  	}
    24  )
    25  
    26  func excludeBinariesByFileOwnershipOverlap(accessor sbomsync.Accessor) {
    27  	accessor.WriteToSBOM(func(s *sbom.SBOM) {
    28  		for _, r := range s.Relationships {
    29  			if excludeBinaryByFileOwnershipOverlap(r, s.Artifacts.Packages) {
    30  				s.Artifacts.Packages.Delete(r.To.ID())
    31  				s.Relationships = RemoveRelationshipsByID(s.Relationships, r.To.ID())
    32  			}
    33  		}
    34  	})
    35  }
    36  
    37  // excludeBinaryByFileOwnershipOverlap will remove packages from a collection given the following properties are true
    38  // 1) the relationship between packages is OwnershipByFileOverlap
    39  // 2) the parent is an "os" package
    40  // 3) the child is a synthetic package generated by the binary cataloger
    41  // 4) the package names are identical
    42  // This was implemented as a way to help resolve: https://github.com/anchore/syft/issues/931
    43  func excludeBinaryByFileOwnershipOverlap(r artifact.Relationship, c *pkg.Collection) bool {
    44  	if artifact.OwnershipByFileOverlapRelationship != r.Type {
    45  		return false
    46  	}
    47  
    48  	parent := c.Package(r.From.ID())
    49  	if parent == nil {
    50  		return false
    51  	}
    52  
    53  	parentInExclusion := slices.Contains(osCatalogerTypes, parent.Type)
    54  	if !parentInExclusion {
    55  		return false
    56  	}
    57  
    58  	child := c.Package(r.To.ID())
    59  	if child == nil {
    60  		return false
    61  	}
    62  
    63  	return slices.Contains(binaryCatalogerTypes, child.Type)
    64  }