Skip to content

Commit e9e9e8c

Browse files
authored
fix(sbom): preserve Red Hat BuildInfo when scanning SBOMs without layer info (#10378)
1 parent f207ec6 commit e9e9e8c

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

pkg/fanal/applier/docker.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,17 @@ func ApplyLayers(layers []ftypes.BlobInfo) ftypes.ArtifactDetail {
212212
}
213213

214214
for i, pkg := range mergedLayer.Packages {
215-
// Skip lookup for SBOM
215+
// Skip lookup for SBOMs obtained from container images (pkg.Layer is already set).
216216
if lo.IsEmpty(pkg.Layer) {
217217
originLayerDigest, originLayerDiffID, installedFiles, buildInfo := lookupOriginLayerForPkg(pkg, layers)
218218
mergedLayer.Packages[i].Layer = ftypes.Layer{
219219
Digest: originLayerDigest,
220220
DiffID: originLayerDiffID,
221221
}
222-
mergedLayer.Packages[i].BuildInfo = buildInfo
222+
// Do not overwrite BuildInfo if it is already set (e.g. packages from SBOMs generated by trivy rootfs).
223+
if buildInfo != nil {
224+
mergedLayer.Packages[i].BuildInfo = buildInfo
225+
}
223226
// Debian/Ubuntu has the installed files only in the first layer where the package is installed.
224227
mergedLayer.Packages[i].InstalledFiles = installedFiles
225228
}

pkg/fanal/applier/docker_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,72 @@ func TestApplyLayers(t *testing.T) {
13811381
},
13821382
},
13831383
},
1384+
{
1385+
name: "SBOM generated by trivy rootfs preserves package-level BuildInfo",
1386+
inputLayers: []types.BlobInfo{
1387+
{
1388+
SchemaVersion: 1,
1389+
PackageInfos: []types.PackageInfo{
1390+
{
1391+
FilePath: "var/lib/rpm/Packages",
1392+
Packages: types.Packages{
1393+
{
1394+
Name: "openssl",
1395+
Version: "1.2.3",
1396+
Release: "4",
1397+
// pkg.Layer is empty: packages in SBOM files do not contain
1398+
// layer information (e.g. SBOMs generated via trivy rootfs).
1399+
// BuildInfo is already set from the SBOM content sets.
1400+
BuildInfo: &types.BuildInfo{
1401+
ContentSets: []string{
1402+
"rhel-8-for-x86_64-baseos-eus-rpms__8_DOT_4",
1403+
},
1404+
},
1405+
},
1406+
},
1407+
},
1408+
},
1409+
OS: types.OS{
1410+
Family: "redhat",
1411+
Name: "8",
1412+
},
1413+
},
1414+
},
1415+
want: types.ArtifactDetail{
1416+
OS: types.OS{
1417+
Family: "redhat",
1418+
Name: "8",
1419+
},
1420+
Packages: types.Packages{
1421+
{
1422+
Name: "openssl",
1423+
Version: "1.2.3",
1424+
Release: "4",
1425+
Identifier: types.PkgIdentifier{
1426+
UID: "d56a873f2b8d0fae",
1427+
PURL: &packageurl.PackageURL{
1428+
Type: packageurl.TypeRPM,
1429+
Namespace: "redhat",
1430+
Name: "openssl",
1431+
Version: "1.2.3-4",
1432+
Qualifiers: packageurl.Qualifiers{
1433+
{
1434+
Key: "distro",
1435+
Value: "redhat-8",
1436+
},
1437+
},
1438+
},
1439+
},
1440+
// BuildInfo must be preserved, not overwritten with nil.
1441+
BuildInfo: &types.BuildInfo{
1442+
ContentSets: []string{
1443+
"rhel-8-for-x86_64-baseos-eus-rpms__8_DOT_4",
1444+
},
1445+
},
1446+
},
1447+
},
1448+
},
1449+
},
13841450
{
13851451
name: "same package but different file path", // different hashes
13861452
inputLayers: []types.BlobInfo{

0 commit comments

Comments
 (0)