Skip to content

Commit

Permalink
fix(apk): find secdb entries for origin packages (#1602)
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Luhring <[email protected]>
  • Loading branch information
luhring authored Sep 16, 2024
1 parent 78945be commit c40aab2
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 9 deletions.
24 changes: 16 additions & 8 deletions grype/matcher/apk/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ func (m *Matcher) Type() match.MatcherType {
func (m *Matcher) Match(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
var matches = make([]match.Match, 0)

// direct matches with package
directMatches, err := m.findApkPackage(store, d, p)
// direct matches with package itself
directMatches, err := m.findMatchesForPackage(store, d, p)
if err != nil {
return nil, err
}
matches = append(matches, directMatches...)

// indirect matches with package source
indirectMatches, err := m.matchBySourceIndirection(store, d, p)
// indirect matches, via package's origin package
indirectMatches, err := m.findMatchesForOriginPackage(store, d, p)
if err != nil {
return nil, err
}
Expand All @@ -61,6 +61,14 @@ func (m *Matcher) cpeMatchesWithoutSecDBFixes(store vulnerability.Provider, d *d
return nil, err
}

for _, upstreamPkg := range pkg.UpstreamPackages(p) {
secDBVulnerabilitiesForUpstream, err := store.GetByDistro(d, upstreamPkg)
if err != nil {
return nil, err
}
secDBVulnerabilities = append(secDBVulnerabilities, secDBVulnerabilitiesForUpstream...)
}

secDBVulnerabilitiesByID := vulnerabilitiesByID(secDBVulnerabilities)

verObj, err := version.NewVersionFromPkg(p)
Expand Down Expand Up @@ -139,8 +147,8 @@ func vulnerabilitiesByID(vulns []vulnerability.Vulnerability) map[string][]vulne
return results
}

func (m *Matcher) findApkPackage(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
// find Alpine SecDB matches for the given package name and version
func (m *Matcher) findMatchesForPackage(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
// find SecDB matches for the given package name and version
secDBMatches, err := search.ByPackageDistro(store, d, p, m.Type())
if err != nil {
return nil, err
Expand All @@ -163,11 +171,11 @@ func (m *Matcher) findApkPackage(store vulnerability.Provider, d *distro.Distro,
return matches, nil
}

func (m *Matcher) matchBySourceIndirection(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
func (m *Matcher) findMatchesForOriginPackage(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
var matches []match.Match

for _, indirectPackage := range pkg.UpstreamPackages(p) {
indirectMatches, err := m.findApkPackage(store, d, indirectPackage)
indirectMatches, err := m.findMatchesForPackage(store, d, indirectPackage)
if err != nil {
return nil, fmt.Errorf("failed to find vulnerabilities for apk upstream source package: %w", err)
}
Expand Down
58 changes: 57 additions & 1 deletion grype/matcher/apk/matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type mockStore struct {
}

func (s *mockStore) GetVulnerability(namespace, id string) ([]grypeDB.Vulnerability, error) {
//TODO implement me
// TODO implement me
panic("implement me")
}

Expand Down Expand Up @@ -556,6 +556,62 @@ func TestNvdMatchesNoConstraintWithSecDBFix(t *testing.T) {
assertMatches(t, expected, actual)
}

func TestNVDMatchCanceledByOriginPackageInSecDB(t *testing.T) {
nvdVuln := grypeDB.Vulnerability{
ID: "CVE-2015-3211",
VersionFormat: "unknown",
CPEs: []string{"cpe:2.3:a:php-fpm:php-fpm:-:*:*:*:*:*:*:*"},
Namespace: "nvd:cpe",
}
secDBVuln := grypeDB.Vulnerability{
ID: "CVE-2015-3211",
VersionConstraint: "< 0",
VersionFormat: "apk",
Namespace: "wolfi:distro:wolfi:rolling",
}
store := mockStore{
backend: map[string]map[string][]grypeDB.Vulnerability{
"nvd:cpe": {
"php-fpm": []grypeDB.Vulnerability{nvdVuln},
},
"wolfi:distro:wolfi:rolling": {
"php-8.3": []grypeDB.Vulnerability{secDBVuln},
},
},
}

provider, err := db.NewVulnerabilityProvider(&store)
require.NoError(t, err)

m := Matcher{}
d, err := distro.New(distro.Wolfi, "")
if err != nil {
t.Fatalf("failed to create a new distro: %+v", err)
}
p := pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "php-8.3-fpm",
Version: "8.3.11-r0",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:php-fpm:php-fpm:8.3.11-r0:*:*:*:*:*:*:*", ""),
},
Upstreams: []pkg.UpstreamPackage{
{
Name: "php-8.3",
Version: "8.3.11-r0",
},
},
}

expected := []match.Match{}

actual, err := m.Match(provider, d, p)
assert.NoError(t, err)

assertMatches(t, expected, actual)
}

func TestDistroMatchBySourceIndirection(t *testing.T) {

secDbVuln := grypeDB.Vulnerability{
Expand Down

0 comments on commit c40aab2

Please sign in to comment.