Skip to content

Commit

Permalink
fix: interpret constraints correctly for Amazon Linux Kernel advisori…
Browse files Browse the repository at this point in the history
…es (#149)

Signed-off-by: Weston Steimel <weston.steimel@anchore.com>
  • Loading branch information
westonsteimel authored Aug 25, 2023
1 parent 5b7c583 commit 500c18a
Show file tree
Hide file tree
Showing 16 changed files with 1,205 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
[
{
"Vulnerability": {
"Name": "ALAS-2021-1704",
"NamespaceName": "amzn:2",
"Description": "",
"Severity": "Medium",
"Metadata": {
"CVE": [
{
"Name": "CVE-2021-3653"
},
{
"Name": "CVE-2021-3656"
},
{
"Name": "CVE-2021-3732"
}
]
},
"Link": "https://alas.aws.amazon.com/AL2/ALAS-2021-1704.html",
"FixedIn": [
{
"Name": "kernel-headers",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "4.14.246-187.474.amzn2"
},
{
"Name": "kernel",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "4.14.246-187.474.amzn2"
}
]
}
},
{
"Vulnerability": {
"Name": "ALASKERNEL-5.4-2022-007",
"NamespaceName": "amzn:2",
"Description": "",
"Severity": "Medium",
"Metadata": {
"CVE": [
{
"Name": "CVE-2021-3753"
},
{
"Name": "CVE-2021-40490"
}
]
},
"Link": "https://alas.aws.amazon.com/AL2/ALASKERNEL-5.4-2022-007.html",
"FixedIn": [
{
"Name": "kernel-headers",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.4.144-69.257.amzn2"
},
{
"Name": "kernel",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.4.144-69.257.amzn2"
}
]
}
},
{
"Vulnerability": {
"Name": "ALASKERNEL-5.10-2022-005",
"NamespaceName": "amzn:2",
"Description": "",
"Severity": "Medium",
"Metadata": {
"CVE": [
{
"Name": "CVE-2021-3753"
},
{
"Name": "CVE-2021-40490"
}
]
},
"Link": "https://alas.aws.amazon.com/AL2/ALASKERNEL-5.10-2022-005.html",
"FixedIn": [
{
"Name": "kernel-headers",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.10.62-55.141.amzn2"
},
{
"Name": "kernel",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.10.62-55.141.amzn2"
}
]
}
}
]
27 changes: 24 additions & 3 deletions pkg/process/v1/transformers/os/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func Transform(vulnerability unmarshal.OSVulnerability) ([]data.Entry, error) {
vuln := grypeDB.Vulnerability{
ID: vulnerability.Vulnerability.Name,
RecordSource: recordSource,
VersionConstraint: enforceConstraint(advisory.Version, advisory.VersionFormat),
VersionConstraint: enforceConstraint(advisory.Version, advisory.VersionFormat, vulnerability.Vulnerability.Name),
VersionFormat: advisory.VersionFormat,
PackageName: advisory.Name,
Namespace: advisory.NamespaceName,
Expand Down Expand Up @@ -82,7 +82,28 @@ func Transform(vulnerability unmarshal.OSVulnerability) ([]data.Entry, error) {
return transformers.NewEntries(allVulns, metadata), nil
}

func enforceConstraint(constraint, format string) string {
func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {
constraint := fmt.Sprintf("< %s", fixVersion)

if strings.HasPrefix(vulnerabilityID, "ALASKERNEL-") {
// Amazon advisories of the form ALASKERNEL-5.4-2023-048 should be interpreted as only applying to
// the 5.4.x kernel line since Amazon issue a separate advisory per affected line, thus the constraint
// should be >= 5.4, < {fix version}. In the future the vunnel schema for OS vulns should be enhanced
// to emit actual constraints rather than fixed-in entries (tracked in https://github.com/anchore/vunnel/issues/266)
// at which point this workaround in grype-db can be removed.

components := strings.Split(vulnerabilityID, "-")

if len(components) == 4 {
base := components[1]
constraint = fmt.Sprintf(">= %s, < %s", base, fixVersion)
}
}

return constraint
}

func enforceConstraint(constraint, format, vulnerabilityID string) string {
constraint = common.CleanConstraint(constraint)
if len(constraint) == 0 {
return ""
Expand All @@ -92,6 +113,6 @@ func enforceConstraint(constraint, format string) string {
return common.EnforceSemVerConstraint(constraint)
default:
// the passed constraint is a fixed version
return fmt.Sprintf("< %s", constraint)
return deriveConstraintFromFix(constraint, vulnerabilityID)
}
}
69 changes: 68 additions & 1 deletion pkg/process/v1/transformers/os/transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,73 @@ func TestParseVulnerabilitiesAllEntries(t *testing.T) {
},
},
},
{
name: "Amazon",
numEntries: 3,
fixture: "test-fixtures/amazon-multiple-kernel-advisories.json",
vulns: []grypeDB.Vulnerability{
{
ID: "ALAS-2021-1704",
RecordSource: "vulnerabilities:amzn:2",
PackageName: "kernel-headers",
VersionConstraint: "< 4.14.246-187.474.amzn2",
VersionFormat: "rpm",
Namespace: "amzn:2",
ProxyVulnerabilities: []string{"CVE-2021-3653", "CVE-2021-3656", "CVE-2021-3732"},
FixedInVersion: "4.14.246-187.474.amzn2",
},
{
ID: "ALAS-2021-1704",
RecordSource: "vulnerabilities:amzn:2",
PackageName: "kernel",
VersionConstraint: "< 4.14.246-187.474.amzn2",
VersionFormat: "rpm",
Namespace: "amzn:2",
ProxyVulnerabilities: []string{"CVE-2021-3653", "CVE-2021-3656", "CVE-2021-3732"},
FixedInVersion: "4.14.246-187.474.amzn2",
},
{
ID: "ALASKERNEL-5.4-2022-007",
RecordSource: "vulnerabilities:amzn:2",
PackageName: "kernel-headers",
VersionConstraint: ">= 5.4, < 5.4.144-69.257.amzn2",
VersionFormat: "rpm",
Namespace: "amzn:2",
ProxyVulnerabilities: []string{"CVE-2021-3753", "CVE-2021-40490"},
FixedInVersion: "5.4.144-69.257.amzn2",
},
{
ID: "ALASKERNEL-5.4-2022-007",
RecordSource: "vulnerabilities:amzn:2",
PackageName: "kernel",
VersionConstraint: ">= 5.4, < 5.4.144-69.257.amzn2",
VersionFormat: "rpm",
Namespace: "amzn:2",
ProxyVulnerabilities: []string{"CVE-2021-3753", "CVE-2021-40490"},
FixedInVersion: "5.4.144-69.257.amzn2",
},
{
ID: "ALASKERNEL-5.10-2022-005",
RecordSource: "vulnerabilities:amzn:2",
PackageName: "kernel-headers",
VersionConstraint: ">= 5.10, < 5.10.62-55.141.amzn2",
VersionFormat: "rpm",
Namespace: "amzn:2",
ProxyVulnerabilities: []string{"CVE-2021-3753", "CVE-2021-40490"},
FixedInVersion: "5.10.62-55.141.amzn2",
},
{
ID: "ALASKERNEL-5.10-2022-005",
RecordSource: "vulnerabilities:amzn:2",
PackageName: "kernel",
VersionConstraint: ">= 5.10, < 5.10.62-55.141.amzn2",
VersionFormat: "rpm",
Namespace: "amzn:2",
ProxyVulnerabilities: []string{"CVE-2021-3753", "CVE-2021-40490"},
FixedInVersion: "5.10.62-55.141.amzn2",
},
},
},
}

for _, test := range tests {
Expand All @@ -394,7 +461,7 @@ func TestParseVulnerabilitiesAllEntries(t *testing.T) {

entries, err := unmarshal.OSVulnerabilityEntries(f)
assert.NoError(t, err)
assert.Len(t, entries, len(test.vulns))
assert.Len(t, entries, test.numEntries)

var vulns []grypeDB.Vulnerability
for _, entry := range entries {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
[
{
"Vulnerability": {
"Name": "ALAS-2021-1704",
"NamespaceName": "amzn:2",
"Description": "",
"Severity": "Medium",
"Metadata": {
"CVE": [
{
"Name": "CVE-2021-3653"
},
{
"Name": "CVE-2021-3656"
},
{
"Name": "CVE-2021-3732"
}
]
},
"Link": "https://alas.aws.amazon.com/AL2/ALAS-2021-1704.html",
"FixedIn": [
{
"Name": "kernel-headers",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "4.14.246-187.474.amzn2"
},
{
"Name": "kernel",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "4.14.246-187.474.amzn2"
}
]
}
},
{
"Vulnerability": {
"Name": "ALASKERNEL-5.4-2022-007",
"NamespaceName": "amzn:2",
"Description": "",
"Severity": "Medium",
"Metadata": {
"CVE": [
{
"Name": "CVE-2021-3753"
},
{
"Name": "CVE-2021-40490"
}
]
},
"Link": "https://alas.aws.amazon.com/AL2/ALASKERNEL-5.4-2022-007.html",
"FixedIn": [
{
"Name": "kernel-headers",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.4.144-69.257.amzn2"
},
{
"Name": "kernel",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.4.144-69.257.amzn2"
}
]
}
},
{
"Vulnerability": {
"Name": "ALASKERNEL-5.10-2022-005",
"NamespaceName": "amzn:2",
"Description": "",
"Severity": "Medium",
"Metadata": {
"CVE": [
{
"Name": "CVE-2021-3753"
},
{
"Name": "CVE-2021-40490"
}
]
},
"Link": "https://alas.aws.amazon.com/AL2/ALASKERNEL-5.10-2022-005.html",
"FixedIn": [
{
"Name": "kernel-headers",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.10.62-55.141.amzn2"
},
{
"Name": "kernel",
"NamespaceName": "amzn:2",
"VersionFormat": "rpm",
"Version": "5.10.62-55.141.amzn2"
}
]
}
}
]
27 changes: 24 additions & 3 deletions pkg/process/v2/transformers/os/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func Transform(vulnerability unmarshal.OSVulnerability) ([]data.Entry, error) {
vuln := grypeDB.Vulnerability{
ID: vulnerability.Vulnerability.Name,
RecordSource: recordSource,
VersionConstraint: enforceConstraint(advisory.Version, advisory.VersionFormat),
VersionConstraint: enforceConstraint(advisory.Version, advisory.VersionFormat, vulnerability.Vulnerability.Name),
VersionFormat: advisory.VersionFormat,
PackageName: advisory.Name,
Namespace: advisory.NamespaceName,
Expand Down Expand Up @@ -82,7 +82,28 @@ func Transform(vulnerability unmarshal.OSVulnerability) ([]data.Entry, error) {
return transformers.NewEntries(allVulns, metadata), nil
}

func enforceConstraint(constraint, format string) string {
func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {
constraint := fmt.Sprintf("< %s", fixVersion)

if strings.HasPrefix(vulnerabilityID, "ALASKERNEL-") {
// Amazon advisories of the form ALASKERNEL-5.4-2023-048 should be interpreted as only applying to
// the 5.4.x kernel line since Amazon issue a separate advisory per affected line, thus the constraint
// should be >= 5.4, < {fix version}. In the future the vunnel schema for OS vulns should be enhanced
// to emit actual constraints rather than fixed-in entries (tracked in https://github.com/anchore/vunnel/issues/266)
// at which point this workaround in grype-db can be removed.

components := strings.Split(vulnerabilityID, "-")

if len(components) == 4 {
base := components[1]
constraint = fmt.Sprintf(">= %s, < %s", base, fixVersion)
}
}

return constraint
}

func enforceConstraint(constraint, format, vulnerabilityID string) string {
constraint = common.CleanConstraint(constraint)
if len(constraint) == 0 {
return ""
Expand All @@ -92,6 +113,6 @@ func enforceConstraint(constraint, format string) string {
return common.EnforceSemVerConstraint(constraint)
default:
// the passed constraint is a fixed version
return fmt.Sprintf("< %s", constraint)
return deriveConstraintFromFix(constraint, vulnerabilityID)
}
}
Loading

0 comments on commit 500c18a

Please sign in to comment.