Skip to content

manually add CVE-2022-3602 and CVE-2022-3786 for ubuntu:22.04 #997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Nov 2, 2022
20 changes: 5 additions & 15 deletions cmd/updater/diffdumps/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/stackrox/scanner/ext/vulnsrc/alpine"
"github.com/stackrox/scanner/ext/vulnsrc/ubuntu"
"github.com/stackrox/scanner/pkg/vulndump"
"github.com/stackrox/scanner/pkg/vulnkey"
"github.com/stackrox/scanner/pkg/vulnloader/istioloader"
"github.com/stackrox/scanner/pkg/vulnloader/k8sloader"
"github.com/stackrox/scanner/pkg/vulnloader/nvdloader"
Expand Down Expand Up @@ -224,18 +225,6 @@ func generateNVDDiffs(outputDir string, baseLastModifiedTime time.Time, headZipR
return nil
}

type clairVulnUniqueKey struct {
name string
namespace string
}

func keyFromVuln(v *database.Vulnerability) clairVulnUniqueKey {
return clairVulnUniqueKey{
name: v.Name,
namespace: v.Namespace.Name,
}
}

type stringPair struct {
first string
second string
Expand Down Expand Up @@ -331,11 +320,11 @@ func generateOSVulnsDiff(outputDir string, baseZipR, headZipR *zip.Reader, cfg c
return errors.Wrap(err, "loading OS vulns from head dump")
}

baseVulnsMap := make(map[clairVulnUniqueKey]database.Vulnerability, len(baseVulns))
baseVulnsMap := make(map[vulnkey.Key]database.Vulnerability, len(baseVulns))
for i := range baseVulns {
// This removes the possibility of memory aliasing.
vuln := baseVulns[i]
key := keyFromVuln(&vuln)
key := vulnkey.FromVuln(&vuln)
if _, ok := baseVulnsMap[key]; ok {
// Should really never happen, but being defensive.
return errors.Errorf("UNEXPECTED: got multiple vulns for key: %v", key)
Expand Down Expand Up @@ -368,7 +357,7 @@ func generateOSVulnsDiff(outputDir string, baseZipR, headZipR *zip.Reader, cfg c

updateAlpineLink(cfg, &headVuln)

key := keyFromVuln(&headVuln)
key := vulnkey.FromVuln(&headVuln)
matchingBaseVuln, found := baseVulnsMap[key]
// If the vuln was in the base, and equal to what was in the base,
// skip it. Else, add.
Expand All @@ -385,6 +374,7 @@ func generateOSVulnsDiff(outputDir string, baseZipR, headZipR *zip.Reader, cfg c
filtered = filterFixableCentOSVulns(filtered)
log.Infof("Skipping fixable centOS vulns: filtered out %d", countBefore-len(filtered))
}

log.Infof("Diffed OS vulns; base had %d, head had %d, and the diff has %d", len(baseVulns), len(headVulns), len(filtered))
if err := vulndump.WriteOSVulns(outputDir, filtered); err != nil {
return err
Expand Down
43 changes: 33 additions & 10 deletions cmd/updater/generatedump/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import (
"github.com/stackrox/scanner/ext/vulnmdsrc"
"github.com/stackrox/scanner/ext/vulnmdsrc/types"
"github.com/stackrox/scanner/ext/vulnsrc"
"github.com/stackrox/scanner/ext/vulnsrc/manual"
"github.com/stackrox/scanner/pkg/rhelv2"
"github.com/stackrox/scanner/pkg/vulndump"
"github.com/stackrox/scanner/pkg/vulnkey"
"github.com/stackrox/scanner/pkg/vulnloader"

// Needed to register all vuln loaders.
Expand Down Expand Up @@ -108,10 +110,17 @@ func Command() *cobra.Command {
func fetchVulns(datastore vulnsrc.DataStore, dumpDir string) (vulns []database.Vulnerability, err error) {
errSig := concurrency.NewErrorSignal()

updaters := vulnsrc.Updaters()
defer func() {
for _, u := range updaters {
u.Clean()
}
}()

// Fetch updates in parallel.
log.Info("fetching vulnerability updates")
responseC := make(chan *vulnsrc.UpdateResponse)
for n, u := range vulnsrc.Updaters() {
for n, u := range updaters {
go func(name string, u vulnsrc.Updater) {
response, err := u.Update(datastore)
if err != nil {
Expand All @@ -129,14 +138,8 @@ func fetchVulns(datastore vulnsrc.DataStore, dumpDir string) (vulns []database.V
}(n, u)
}

defer func() {
for _, updaters := range vulnsrc.Updaters() {
updaters.Clean()
}
}()

// Collect results of updates.
for i := 0; i < len(vulnsrc.Updaters()); i++ {
for range updaters {
select {
case resp := <-responseC:
vulns = append(vulns, doVulnerabilitiesNamespacing(resp.Vulnerabilities)...)
Expand All @@ -152,6 +155,26 @@ func fetchVulns(datastore vulnsrc.DataStore, dumpDir string) (vulns []database.V
if err != nil {
return nil, errors.Wrap(err, "adding metadata to vulns")
}

// Add manual vulnerabilities ONLY if they do not already exist due to some other source.
manualVulns := make(map[vulnkey.Key]database.Vulnerability, len(manual.Vulnerabilities))
for _, vuln := range manual.Vulnerabilities {
// Prevent aliasing.
vuln := vuln
manualVulns[vulnkey.FromVuln(&vuln)] = vuln
}
for _, vuln := range vulnsWithMetadata {
// Prevent aliasing.
vuln := vuln
key := vulnkey.FromVuln(&vuln)
// Delete the vulnerability from the manual entries if it is already populated from another source.
delete(manualVulns, key)
}
for _, vuln := range manualVulns {
vulnsWithMetadata = append(vulnsWithMetadata, vuln)
log.Infof("Manually adding %s for %s", vuln.Name, vuln.Namespace.Name)
}

return vulnsWithMetadata, nil
}

Expand Down Expand Up @@ -222,8 +245,8 @@ func isValidVuln(vuln *database.Vulnerability) bool {
// and only contains the FixedIn FeatureVersions corresponding to their
// Namespace.
//
// It helps simplifying the fetchers that share the same metadata about a
// Vulnerability regardless of their actual namespace (ie. same vulnerability
// It helps simplify the fetchers that share the same metadata about a
// Vulnerability regardless of their actual namespace (i.e. same vulnerability
// information for every version of a distro).
func doVulnerabilitiesNamespacing(nonNamespacedVulns []database.Vulnerability) []database.Vulnerability {
namespacedVulnsMap := make(map[string]*database.Vulnerability)
Expand Down
69 changes: 69 additions & 0 deletions e2etests/testcase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3603,4 +3603,73 @@ Applications using RegexRequestMatcher with '.' in the regular expression are po
},
},
},
{
image: "quay.io/rhacs-eng/qa:ubuntu-22.04-openssl",
registry: "https://quay.io",
username: os.Getenv("QUAY_RHACS_ENG_RO_USERNAME"),
password: os.Getenv("QUAY_RHACS_ENG_RO_PASSWORD"),
source: "NVD",
onlyCheckSpecifiedVulns: true,
namespace: "ubuntu:22.04",
expectedFeatures: []apiV1.Feature{
{
Name: "openssl",
NamespaceName: "ubuntu:22.04",
VersionFormat: "dpkg",
Version: "3.0.2-0ubuntu1.6",
Vulnerabilities: []apiV1.Vulnerability{
{
Name: "CVE-2022-3602",
Description: "X.509 Email Address Buffer Overflow",
Link: "https://ubuntu.com/security/CVE-2022-3602",
Severity: "Important",
Metadata: map[string]interface{}{
"NVD": map[string]interface{}{
"CVSSv2": map[string]interface{}{
"ExploitabilityScore": 0.0,
"ImpactScore": 0.0,
"Score": 0.0,
"Vectors": "",
},
"CVSSv3": map[string]interface{}{
"ExploitabilityScore": 2.8,
"ImpactScore": 5.9,
"Score": 8.8,
"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
},
},
},
FixedBy: "3.0.2-0ubuntu1.7",
},
{
Name: "CVE-2022-3786",
Description: "X.509 Email Address Buffer Overflow",
Link: "https://ubuntu.com/security/CVE-2022-3786",
Severity: "Important",
Metadata: map[string]interface{}{
"NVD": map[string]interface{}{
"CVSSv2": map[string]interface{}{
"ExploitabilityScore": 0.0,
"ImpactScore": 0.0,
"Score": 0.0,
"Vectors": "",
},
"CVSSv3": map[string]interface{}{
"ExploitabilityScore": 3.9,
"ImpactScore": 3.6,
"Score": 7.5,
"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
},
},
},
FixedBy: "3.0.2-0ubuntu1.7",
},
},
// TODO: Why is this empty?
FixedBy: "",
// TODO: Why is it this layer?
AddedBy: "sha256:301a8b74f71f85f3a31e9c7e7fedd5b001ead5bcf895bc2911c1d260e06bd987",
},
},
},
}
2 changes: 1 addition & 1 deletion ext/vulnsrc/all/all.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package all

import (
// Import all the vulnsrc providers.
// Import all the vulnsrc providers EXCEPT for the manual source.
_ "github.com/stackrox/scanner/ext/vulnsrc/alpine"
_ "github.com/stackrox/scanner/ext/vulnsrc/amzn"
_ "github.com/stackrox/scanner/ext/vulnsrc/debian"
Expand Down
106 changes: 106 additions & 0 deletions ext/vulnsrc/manual/manual.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package manual

import (
log "github.com/sirupsen/logrus"
"github.com/stackrox/scanner/database"
"github.com/stackrox/scanner/ext/versionfmt/dpkg"
"github.com/stackrox/scanner/ext/vulnsrc"
)

var _ vulnsrc.Updater = (*updater)(nil)

type updater struct {
}

// Vulnerabilities lists vulnerabilities which may not already exist in the feeds for other distros.
var Vulnerabilities = []database.Vulnerability{
{
Name: "CVE-2022-3602",
Namespace: database.Namespace{
Name: "ubuntu:22.04",
VersionFormat: dpkg.ParserName,
},
Description: "X.509 Email Address Buffer Overflow",
Link: "https://ubuntu.com/security/CVE-2022-3602",
Severity: database.HighSeverity,
FixedIn: []database.FeatureVersion{
{
Feature: database.Feature{
Name: "openssl",
Namespace: database.Namespace{
Name: "ubuntu:22.04",
VersionFormat: dpkg.ParserName,
},
},
Version: "3.0.2-0ubuntu1.7",
},
},
Metadata: map[string]interface{}{
"NVD": map[string]interface{}{
"PublishedDateTime": "2022-11-01T16:00Z",
"LastModifiedDateTime": "2022-11-01T16:00Z",
"CVSSv2": map[string]interface{}{
"ExploitabilityScore": 0.0,
"ImpactScore": 0.0,
"Score": 0.0,
"Vectors": "",
},
"CVSSv3": map[string]interface{}{
"ExploitabilityScore": 2.8,
"ImpactScore": 5.9,
"Score": 8.8,
"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
},
},
},
},
{
Name: "CVE-2022-3786",
Namespace: database.Namespace{
Name: "ubuntu:22.04",
VersionFormat: dpkg.ParserName,
},
Description: "X.509 Email Address Buffer Overflow",
Link: "https://ubuntu.com/security/CVE-2022-3786",
Severity: database.HighSeverity,
FixedIn: []database.FeatureVersion{
{
Feature: database.Feature{
Name: "openssl",
Namespace: database.Namespace{
Name: "ubuntu:22.04",
VersionFormat: dpkg.ParserName,
},
},
Version: "3.0.2-0ubuntu1.7",
},
},
Metadata: map[string]interface{}{
"NVD": map[string]interface{}{
"PublishedDateTime": "2022-11-01T16:00Z",
"LastModifiedDateTime": "2022-11-01T16:00Z",
"CVSSv2": map[string]interface{}{
"ExploitabilityScore": 0.0,
"ImpactScore": 0.0,
"Score": 0.0,
"Vectors": "",
},
"CVSSv3": map[string]interface{}{
"ExploitabilityScore": 3.9,
"ImpactScore": 3.6,
"Score": 7.5,
"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
},
},
},
},
}

func (u updater) Update(_ vulnsrc.DataStore) (resp vulnsrc.UpdateResponse, _ error) {
log.WithField("package", "Manual Entries").Info("Start fetching vulnerabilities")

resp.Vulnerabilities = Vulnerabilities
return
}

func (u updater) Clean() {}
18 changes: 18 additions & 0 deletions pkg/vulnkey/key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package vulnkey

import "github.com/stackrox/scanner/database"

// Key represents a unique identified for a vulnerability to be used as a key.
type Key struct {
name string
namespace string
}

// FromVuln creates a Key from the given *database.Vulnerability.
// It is expected the vulnerability is not nil and the namespace is not nil.
func FromVuln(v *database.Vulnerability) Key {
return Key{
name: v.Name,
namespace: v.Namespace.Name,
}
}