fix: de-duplicate same dpkg packages with different filePaths from different layers (#8298)

This commit is contained in:
DmitriyLewen
2025-01-28 13:03:33 +06:00
committed by GitHub
parent d749b621c8
commit 846498dd23
3 changed files with 65 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
package applier
import (
"cmp"
"fmt"
"strings"
"time"
@@ -13,7 +14,9 @@ import (
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/purl"
"github.com/aquasecurity/trivy/pkg/scanner/utils"
"github.com/aquasecurity/trivy/pkg/types"
xslices "github.com/aquasecurity/trivy/pkg/x/slices"
)
type Config struct {
@@ -232,6 +235,12 @@ func ApplyLayers(layers []ftypes.BlobInfo) ftypes.ArtifactDetail {
}
}
// De-duplicate same debian packages from different dirs
// cf. https://github.com/aquasecurity/trivy/issues/8297
mergedLayer.Packages = xslices.ZeroToNil(lo.UniqBy(mergedLayer.Packages, func(pkg ftypes.Package) string {
return cmp.Or(pkg.ID, fmt.Sprintf("%s@%s", pkg.Name, utils.FormatVersion(pkg)))
}))
for _, app := range mergedLayer.Applications {
for i, pkg := range app.Packages {
// Skip lookup for SBOM

View File

@@ -254,6 +254,61 @@ func TestApplyLayers(t *testing.T) {
},
},
},
{
name: "happy path with duplicate of debian packages",
inputLayers: []types.BlobInfo{
{
SchemaVersion: 2,
DiffID: "sha256:96e320b34b5478d8b369ca43ffaa88ff6dd9499ec72b792ca21b1e8b0c55670f",
PackageInfos: []types.PackageInfo{
{
FilePath: "var/lib/dpkg/status.d/libssl1",
Packages: types.Packages{
{
ID: "libssl1.1@1.1.1n-0+deb11u3",
Name: "libssl1.1",
Version: "1.1.1n",
Release: "0+deb11u3",
},
},
},
},
},
{
SchemaVersion: 2,
DiffID: "sha256:5e087d956f3e62bd034dd0712bc4cbef8fda55fba0b11a7d0564f294887c7079",
PackageInfos: []types.PackageInfo{
{
FilePath: "var/lib/dpkg/status.d/libssl1.1",
Packages: types.Packages{
{
ID: "libssl1.1@1.1.1n-0+deb11u3",
Name: "libssl1.1",
Version: "1.1.1n",
Release: "0+deb11u3",
},
},
},
},
},
},
want: types.ArtifactDetail{
Packages: types.Packages{
{
ID: "libssl1.1@1.1.1n-0+deb11u3",
Name: "libssl1.1",
Version: "1.1.1n",
Release: "0+deb11u3",
Identifier: types.PkgIdentifier{
UID: "522a5c3b263d1357",
},
Layer: types.Layer{
DiffID: "sha256:96e320b34b5478d8b369ca43ffaa88ff6dd9499ec72b792ca21b1e8b0c55670f",
},
},
},
},
},
{
name: "happy path with digests in libs/packages (as for SBOM)",
inputLayers: []types.BlobInfo{

View File

@@ -1,5 +1,6 @@
package slices
// ZeroToNil returns nil, if slice is empty
func ZeroToNil[T any](t []T) []T {
if len(t) == 0 {
return nil