From e64eeddfb37326eef695898ce6227e7088c0275f Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 23 Dec 2024 16:51:03 -0500 Subject: [PATCH] have aliases for non standard names (#2351) Signed-off-by: Alex Goodman --- grype/db/v6/affected_package_store.go | 2 +- grype/db/v6/affected_package_store_test.go | 70 ++++++++++++++++++++++ grype/db/v6/models.go | 28 +++++---- grype/db/v6/models_test.go | 6 +- 4 files changed, 92 insertions(+), 14 deletions(-) diff --git a/grype/db/v6/affected_package_store.go b/grype/db/v6/affected_package_store.go index 56a5888d11d..da8995a7f0c 100644 --- a/grype/db/v6/affected_package_store.go +++ b/grype/db/v6/affected_package_store.go @@ -473,7 +473,7 @@ func (s *affectedPackageStore) applyAlias(d *OSSpecifier) error { } var aliases []OperatingSystemAlias - err := s.db.Where("name = ?", d.Name).Find(&aliases).Error + err := s.db.Where("alias = ?", d.Name).Find(&aliases).Error if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { return fmt.Errorf("failed to resolve alias for distro %q: %w", d.Name, err) diff --git a/grype/db/v6/affected_package_store_test.go b/grype/db/v6/affected_package_store_test.go index 123768d9e3c..e956407b268 100644 --- a/grype/db/v6/affected_package_store_test.go +++ b/grype/db/v6/affected_package_store_test.go @@ -760,6 +760,9 @@ func TestAffectedPackageStore_ResolveDistro(t *testing.T) { arch := &OperatingSystem{Name: "arch", ReleaseID: "arch", MajorVersion: "20241110", MinorVersion: "0"} oracle5 := &OperatingSystem{Name: "oracle", ReleaseID: "ol", MajorVersion: "5"} oracle6 := &OperatingSystem{Name: "oracle", ReleaseID: "ol", MajorVersion: "6"} + amazon2 := &OperatingSystem{Name: "amazon", ReleaseID: "amzn", MajorVersion: "2"} + rocky8 := &OperatingSystem{Name: "rocky", ReleaseID: "rocky", MajorVersion: "8"} // should not be matched + alma8 := &OperatingSystem{Name: "almalinux", ReleaseID: "almalinux", MajorVersion: "8"} // should not be matched operatingSystems := []*OperatingSystem{ ubuntu2004, @@ -775,6 +778,9 @@ func TestAffectedPackageStore_ResolveDistro(t *testing.T) { arch, oracle5, oracle6, + amazon2, + rocky8, + alma8, } require.NoError(t, db.Create(&operatingSystems).Error) @@ -921,6 +927,70 @@ func TestAffectedPackageStore_ResolveDistro(t *testing.T) { }, expected: []OperatingSystem{*oracle5}, }, + { + name: "lookup by non-standard name (oraclelinux)", + distro: OSSpecifier{ + Name: "oraclelinux", // based on the grype distro names + MajorVersion: "5", + }, + expected: []OperatingSystem{*oracle5}, + }, + { + name: "lookup by non-standard name (amazonlinux)", + distro: OSSpecifier{ + Name: "amazonlinux", // based on the grype distro names + MajorVersion: "2", + }, + expected: []OperatingSystem{*amazon2}, + }, + { + name: "lookup by non-standard name (oracle)", + distro: OSSpecifier{ + Name: "oracle", + MajorVersion: "5", + }, + expected: []OperatingSystem{*oracle5}, + }, + { + name: "lookup by non-standard name (amazon)", + distro: OSSpecifier{ + Name: "amazon", + MajorVersion: "2", + }, + expected: []OperatingSystem{*amazon2}, + }, + { + name: "lookup by non-standard name (rocky)", + distro: OSSpecifier{ + Name: "rocky", + MajorVersion: "8", + }, + expected: []OperatingSystem{*rhel8}, + }, + { + name: "lookup by non-standard name (rockylinux)", + distro: OSSpecifier{ + Name: "rockylinux", + MajorVersion: "8", + }, + expected: []OperatingSystem{*rhel8}, + }, + { + name: "lookup by non-standard name (alma)", + distro: OSSpecifier{ + Name: "alma", + MajorVersion: "8", + }, + expected: []OperatingSystem{*rhel8}, + }, + { + name: "lookup by non-standard name (almalinux)", + distro: OSSpecifier{ + Name: "almalinux", + MajorVersion: "8", + }, + expected: []OperatingSystem{*rhel8}, + }, { name: "missing distro name", distro: OSSpecifier{ diff --git a/grype/db/v6/models.go b/grype/db/v6/models.go index 485e1a9dfe8..2a54f30a4d3 100644 --- a/grype/db/v6/models.go +++ b/grype/db/v6/models.go @@ -298,8 +298,8 @@ func (os *OperatingSystem) BeforeCreate(tx *gorm.DB) (err error) { } type OperatingSystemAlias struct { - // Name is the matching name as found in the ID field if the /etc/os-release file - Name string `gorm:"column:name;primaryKey;index:os_alias_idx"` + // Name is alias name for the operating system. + Alias string `gorm:"column:alias;primaryKey;index:os_alias_idx"` // Version is the matching version as found in the VERSION_ID field if the /etc/os-release file Version string `gorm:"column:version;primaryKey"` @@ -319,18 +319,26 @@ type OperatingSystemAlias struct { Rolling bool `gorm:"column:rolling;primaryKey"` } +// TODO: in a future iteration these should be raised up more explicitly by the vunnel providers func KnownOperatingSystemAliases() []OperatingSystemAlias { strRef := func(s string) *string { return &s } return []OperatingSystemAlias{ - {Name: "centos", ReplacementName: strRef("rhel")}, - {Name: "rocky", ReplacementName: strRef("rhel")}, - {Name: "almalinux", ReplacementName: strRef("rhel")}, - {Name: "gentoo", ReplacementName: strRef("rhel")}, - {Name: "alpine", VersionPattern: ".*_alpha.*", ReplacementLabelVersion: strRef("edge"), Rolling: true}, - {Name: "wolfi", Rolling: true}, - {Name: "arch", Rolling: true}, + {Alias: "centos", ReplacementName: strRef("rhel")}, + {Alias: "rocky", ReplacementName: strRef("rhel")}, + {Alias: "rockylinux", ReplacementName: strRef("rhel")}, // non-standard, but common (dockerhub uses "rockylinux") + {Alias: "alma", ReplacementName: strRef("rhel")}, + {Alias: "almalinux", ReplacementName: strRef("rhel")}, // non-standard, but common (dockerhub uses "almalinux") + {Alias: "gentoo", ReplacementName: strRef("rhel")}, + {Alias: "alpine", VersionPattern: ".*_alpha.*", ReplacementLabelVersion: strRef("edge"), Rolling: true}, + {Alias: "wolfi", Rolling: true}, + {Alias: "arch", Rolling: true}, + {Alias: "archlinux", ReplacementName: strRef("arch"), Rolling: true}, // non-standard, but common (dockerhub uses "archlinux") + {Alias: "oracle", ReplacementName: strRef("ol")}, // non-standard, but common + {Alias: "oraclelinux", ReplacementName: strRef("ol")}, // non-standard, but common (dockerhub uses "oraclelinux") + {Alias: "amazon", ReplacementName: strRef("amzn")}, // non-standard, but common + {Alias: "amazonlinux", ReplacementName: strRef("amzn")}, // non-standard, but common (dockerhub uses "amazonlinux") // TODO: trixie is a placeholder for now, but should be updated to sid when the time comes // this needs to be automated, but isn't clear how to do so since you'll see things like this: // @@ -346,7 +354,7 @@ func KnownOperatingSystemAliases() []OperatingSystemAlias { // // depending where the team is during the development cycle you will see different behavior, making automating // this a little challenging. - {Name: "debian", Codename: "trixie", Rolling: true}, // is currently sid, which is considered rolling + {Alias: "debian", Codename: "trixie", Rolling: true}, // is currently sid, which is considered rolling } } diff --git a/grype/db/v6/models_test.go b/grype/db/v6/models_test.go index 0264911be38..a3789d8d51d 100644 --- a/grype/db/v6/models_test.go +++ b/grype/db/v6/models_test.go @@ -20,7 +20,7 @@ func TestOperatingSystemAlias_VersionMutualExclusivity(t *testing.T) { { name: "version and version_pattern are mutually exclusive", input: &OperatingSystemAlias{ - Name: "ubuntu", + Alias: "ubuntu", Version: "20.04", VersionPattern: "20.*", }, @@ -29,7 +29,7 @@ func TestOperatingSystemAlias_VersionMutualExclusivity(t *testing.T) { { name: "only version is set", input: &OperatingSystemAlias{ - Name: "ubuntu", + Alias: "ubuntu", Version: "20.04", }, errMsg: "", @@ -37,7 +37,7 @@ func TestOperatingSystemAlias_VersionMutualExclusivity(t *testing.T) { { name: "only version_pattern is set", input: &OperatingSystemAlias{ - Name: "ubuntu", + Alias: "ubuntu", VersionPattern: "20.*", }, errMsg: "",