mirror of
https://github.com/anchore/grype
synced 2024-09-20 06:21:56 +00:00
fix(apk): find secdb entries for origin packages (#1602)
Signed-off-by: Dan Luhring <dluhring@chainguard.dev>
This commit is contained in:
parent
78945be951
commit
c40aab240f
2 changed files with 73 additions and 9 deletions
|
@ -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) {
|
func (m *Matcher) Match(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
|
||||||
var matches = make([]match.Match, 0)
|
var matches = make([]match.Match, 0)
|
||||||
|
|
||||||
// direct matches with package
|
// direct matches with package itself
|
||||||
directMatches, err := m.findApkPackage(store, d, p)
|
directMatches, err := m.findMatchesForPackage(store, d, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
matches = append(matches, directMatches...)
|
matches = append(matches, directMatches...)
|
||||||
|
|
||||||
// indirect matches with package source
|
// indirect matches, via package's origin package
|
||||||
indirectMatches, err := m.matchBySourceIndirection(store, d, p)
|
indirectMatches, err := m.findMatchesForOriginPackage(store, d, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,14 @@ func (m *Matcher) cpeMatchesWithoutSecDBFixes(store vulnerability.Provider, d *d
|
||||||
return nil, err
|
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)
|
secDBVulnerabilitiesByID := vulnerabilitiesByID(secDBVulnerabilities)
|
||||||
|
|
||||||
verObj, err := version.NewVersionFromPkg(p)
|
verObj, err := version.NewVersionFromPkg(p)
|
||||||
|
@ -139,8 +147,8 @@ func vulnerabilitiesByID(vulns []vulnerability.Vulnerability) map[string][]vulne
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Matcher) findApkPackage(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
|
func (m *Matcher) findMatchesForPackage(store vulnerability.Provider, d *distro.Distro, p pkg.Package) ([]match.Match, error) {
|
||||||
// find Alpine SecDB matches for the given package name and version
|
// find SecDB matches for the given package name and version
|
||||||
secDBMatches, err := search.ByPackageDistro(store, d, p, m.Type())
|
secDBMatches, err := search.ByPackageDistro(store, d, p, m.Type())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -163,11 +171,11 @@ func (m *Matcher) findApkPackage(store vulnerability.Provider, d *distro.Distro,
|
||||||
return matches, nil
|
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
|
var matches []match.Match
|
||||||
|
|
||||||
for _, indirectPackage := range pkg.UpstreamPackages(p) {
|
for _, indirectPackage := range pkg.UpstreamPackages(p) {
|
||||||
indirectMatches, err := m.findApkPackage(store, d, indirectPackage)
|
indirectMatches, err := m.findMatchesForPackage(store, d, indirectPackage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to find vulnerabilities for apk upstream source package: %w", err)
|
return nil, fmt.Errorf("failed to find vulnerabilities for apk upstream source package: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ type mockStore struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *mockStore) GetVulnerability(namespace, id string) ([]grypeDB.Vulnerability, error) {
|
func (s *mockStore) GetVulnerability(namespace, id string) ([]grypeDB.Vulnerability, error) {
|
||||||
//TODO implement me
|
// TODO implement me
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,6 +556,62 @@ func TestNvdMatchesNoConstraintWithSecDBFix(t *testing.T) {
|
||||||
assertMatches(t, expected, actual)
|
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) {
|
func TestDistroMatchBySourceIndirection(t *testing.T) {
|
||||||
|
|
||||||
secDbVuln := grypeDB.Vulnerability{
|
secDbVuln := grypeDB.Vulnerability{
|
||||||
|
|
Loading…
Reference in a new issue