Skip to content

Commit

Permalink
Add release ID to OS models (#457)
Browse files Browse the repository at this point in the history
* add release ID to OS models

Signed-off-by: Alex Goodman <[email protected]>

* bump grype

Signed-off-by: Alex Goodman <[email protected]>

---------

Signed-off-by: Alex Goodman <[email protected]>
  • Loading branch information
wagoodman authored Dec 23, 2024
1 parent 07e7a21 commit c6c23cd
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 28 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/adrg/xdg v0.5.3
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a
github.com/anchore/grype v0.86.2-0.20241218195423-d94e68a680dc
github.com/anchore/grype v0.86.2-0.20241223182831-3baa3d2ca99a
github.com/anchore/syft v1.18.2-0.20241216153735-397eb9c10acd
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/dave/jennifer v1.7.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE+o2gozGEBoUMpX27lsku+xrMwlmBZJtbg=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
github.com/anchore/grype v0.86.2-0.20241218195423-d94e68a680dc h1:DmRYOnqIuu81SZzac60zscLGf/NXQe6FFnNBPoXV71c=
github.com/anchore/grype v0.86.2-0.20241218195423-d94e68a680dc/go.mod h1:rqbEt5hrFdlJ8nrk8VFv0A77XD4gzhkWk8LU9iU77AA=
github.com/anchore/grype v0.86.2-0.20241223182831-3baa3d2ca99a h1:7vWYvOsRaJmFUOk4YKrRdaFGi/SIo32IY8+tcUZiyQk=
github.com/anchore/grype v0.86.2-0.20241223182831-3baa3d2ca99a/go.mod h1:rqbEt5hrFdlJ8nrk8VFv0A77XD4gzhkWk8LU9iU77AA=
github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f h1:dAQPIrQ3a5PBqZeZ+B9NGZsGmodk4NO9OjDIsQmQyQM=
github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI=
github.com/anchore/stereoscope v0.0.11 h1:d+dePyWyQzoQehnWOnx/aISW5HW1zLAQKzvaFIpydsU=
Expand Down
44 changes: 20 additions & 24 deletions pkg/process/v6/transformers/os/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ func getAffectedPackages(vuln unmarshal.OSVulnerability) []grypeDB.AffectedPacka
}

aph := grypeDB.AffectedPackageHandle{
OperatingSystem: getOperatingSystem(group.osName, group.osVersion),
OperatingSystem: getOperatingSystem(group.osName, group.id, group.osVersion),
Package: getPackage(group),

BlobValue: &grypeDB.AffectedPackageBlob{
CVEs: getAliases(vuln),
Qualifiers: qualifiers,
Expand Down Expand Up @@ -170,14 +169,15 @@ func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {

type groupIndex struct {
name string
id string
osName string
osVersion string
module string
}

func groupFixedIns(vuln unmarshal.OSVulnerability) map[groupIndex][]unmarshal.OSFixedIn {
grouped := make(map[groupIndex][]unmarshal.OSFixedIn)
osName, osVersion := getOSInfo(vuln.Vulnerability.NamespaceName)
osName, osID, osVersion := getOSInfo(vuln.Vulnerability.NamespaceName)

for _, fixedIn := range vuln.Vulnerability.FixedIn {
var mod string
Expand All @@ -186,6 +186,7 @@ func groupFixedIns(vuln unmarshal.OSVulnerability) map[groupIndex][]unmarshal.OS
}
g := groupIndex{
name: fixedIn.Name,
id: osID,
osName: osName,
osVersion: osVersion,
module: mod,
Expand Down Expand Up @@ -218,42 +219,36 @@ func getPackage(group groupIndex) *grypeDB.Package {
}
}

func getOSInfo(group string) (string, string) {
// derived from enterprise feed groups, expected to be of the form {distroID}:{version}
func getOSInfo(group string) (string, string, string) {
// derived from enterprise feed groups, expected to be of the form {distro release ID}:{version}
feedGroupComponents := strings.Split(group, ":")

return normalizeOsName(feedGroupComponents[0], feedGroupComponents[1]), feedGroupComponents[1]
}

// add new fields to OS schema: release-id, release-version-id
// update vunnel providers to emit these fields (they are based on the /etc/os-release values)
// update this code to STOP parsing namespace and start using those new fields
// now when a user searches by OS (from the /etc/os-release values) they will get the correct results
// what's missing:
// - when to search by major version vs major.minor version...
// - edge/rolling behavior
// - aliases: user has centos 8, but the feed has rhel 8, use that instead
func normalizeOsName(name, version string) string {
if strings.ToLower(name) == "mariner" {
id := feedGroupComponents[0]
version := feedGroupComponents[1]
if strings.ToLower(id) == "mariner" {
verFields := strings.Split(version, ".")
majorVersionStr := verFields[0]
majorVer, err := strconv.Atoi(majorVersionStr)
if err == nil {
if majorVer >= 3 {
name = string(distro.Azure)
id = string(distro.Azure)
}
}
}
d, ok := distro.IDMapping[name]

return normalizeOsName(id), id, version
}

func normalizeOsName(id string) string {
d, ok := distro.IDMapping[id]
if !ok {
log.WithFields("distro", name).Warn("unknown distro name")
log.WithFields("distro", id).Warn("unknown distro name")

return name
return id
}

distroName := d.String()

// TODO: this doesn't seem right
switch d {
case distro.OracleLinux:
distroName = "oracle"
Expand All @@ -263,7 +258,7 @@ func normalizeOsName(name, version string) string {
return distroName
}

func getOperatingSystem(osName, osVersion string) *grypeDB.OperatingSystem {
func getOperatingSystem(osName, osID, osVersion string) *grypeDB.OperatingSystem {
if osName == "" || osVersion == "" {
return nil
}
Expand All @@ -284,6 +279,7 @@ func getOperatingSystem(osName, osVersion string) *grypeDB.OperatingSystem {

return &grypeDB.OperatingSystem{
Name: osName,
ReleaseID: osID,
MajorVersion: majorVersion,
MinorVersion: minorVersion,
LabelVersion: labelVersion,
Expand Down
137 changes: 136 additions & 1 deletion pkg/process/v6/transformers/os/transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,32 +44,45 @@ func expectedProvider(name string) *grypeDB.Provider {

func TestTransform(t *testing.T) {

alpineOS := &grypeDB.OperatingSystem{
Name: "alpine",
ReleaseID: "alpine",
MajorVersion: "3",
MinorVersion: "9",
}

amazonOS := &grypeDB.OperatingSystem{
Name: "amazon",
ReleaseID: "amzn",
MajorVersion: "2",
}
azure3OS := &grypeDB.OperatingSystem{
Name: "azurelinux",
ReleaseID: "azurelinux",
MajorVersion: "3",
MinorVersion: "0", // TODO: is this right?
}
debian8OS := &grypeDB.OperatingSystem{
Name: "debian",
ReleaseID: "debian",
MajorVersion: "8",
Codename: "jessie",
}

mariner2OS := &grypeDB.OperatingSystem{
Name: "mariner",
ReleaseID: "mariner",
MajorVersion: "2",
MinorVersion: "0", // TODO: is this right?
}
ol8OS := &grypeDB.OperatingSystem{
Name: "oracle",
ReleaseID: "ol",
MajorVersion: "8",
}
rhel8OS := &grypeDB.OperatingSystem{
Name: "redhat",
ReleaseID: "rhel",
MajorVersion: "8",
}
tests := []struct {
Expand Down Expand Up @@ -105,7 +118,7 @@ func TestTransform(t *testing.T) {
},
Related: affectedPkgSlice(
grypeDB.AffectedPackageHandle{
OperatingSystem: &grypeDB.OperatingSystem{Name: "alpine", MajorVersion: "3", MinorVersion: "9"},
OperatingSystem: alpineOS,
Package: &grypeDB.Package{Type: "apk", Name: "xen"},
BlobValue: &grypeDB.AffectedPackageBlob{
Ranges: []grypeDB.AffectedRange{
Expand Down Expand Up @@ -1102,6 +1115,128 @@ func TestTransform(t *testing.T) {
}
}

func TestGetOperatingSystem(t *testing.T) {
tests := []struct {
name string
osName string
osID string
osVersion string
expected *grypeDB.OperatingSystem
}{
{
name: "works with given args",
osName: "alpine",
osID: "alpine",
osVersion: "3.10",
expected: &grypeDB.OperatingSystem{
Name: "alpine",
ReleaseID: "alpine",
MajorVersion: "3",
MinorVersion: "10",
LabelVersion: "",
Codename: "",
},
},
{
name: "does codename lookup (debian)",
osName: "debian",
osID: "debian",
osVersion: "11",
expected: &grypeDB.OperatingSystem{
Name: "debian",
ReleaseID: "debian",
MajorVersion: "11",
MinorVersion: "",
LabelVersion: "",
Codename: "bullseye",
},
},
{
name: "does codename lookup (ubuntu)",
osName: "ubuntu",
osID: "ubuntu",
osVersion: "22.04",
expected: &grypeDB.OperatingSystem{
Name: "ubuntu",
ReleaseID: "ubuntu",
MajorVersion: "22",
MinorVersion: "04",
LabelVersion: "",
Codename: "jammy",
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := getOperatingSystem(tt.osName, tt.osID, tt.osVersion)
require.Equal(t, tt.expected, result)
})
}
}

func TestGetOSInfo(t *testing.T) {
tests := []struct {
name string
group string
expectedOS string
expectedID string
expectedV string
}{
{
name: "alpine 3.10",
group: "alpine:3.10",
expectedOS: "alpine",
expectedID: "alpine",
expectedV: "3.10",
},
{
name: "debian bullseye",
group: "debian:11",
expectedOS: "debian",
expectedID: "debian",
expectedV: "11",
},
{
name: "mariner version 1",
group: "mariner:1.0",
expectedOS: "mariner",
expectedID: "mariner",
expectedV: "1.0",
},
{
name: "mariner version 3 (azurelinux conversion)",
group: "mariner:3.0",
expectedOS: "azurelinux",
expectedID: "azurelinux",
expectedV: "3.0",
},
{
name: "ubuntu focal",
group: "ubuntu:20.04",
expectedOS: "ubuntu",
expectedID: "ubuntu",
expectedV: "20.04",
},
{
name: "oracle linux",
group: "ol:8",
expectedOS: "oracle", // normalize name
expectedID: "ol", // keep original ID
expectedV: "8",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osName, id, version := getOSInfo(tt.group)
require.Equal(t, tt.expectedOS, osName)
require.Equal(t, tt.expectedID, id)
require.Equal(t, tt.expectedV, version)
})
}
}

func affectedPkgSlice(a ...grypeDB.AffectedPackageHandle) []any {
var r []any
for _, v := range a {
Expand Down

0 comments on commit c6c23cd

Please sign in to comment.