Skip to content

Commit d987cac

Browse files
committed
fix: add unaffected results to db search vuln, fix alias results
Signed-off-by: Keith Zantow <kzantow@gmail.com>
1 parent 67d4113 commit d987cac

10 files changed

Lines changed: 459 additions & 15 deletions

cmd/grype/cli/commands/db_search.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ func runDBSearchMatches(opts dbSearchMatchOptions) error {
158158
return err
159159
}
160160

161+
if opts.Vulnerability.IncludeAliases {
162+
for i := range opts.Vulnerability.Specs {
163+
opts.Vulnerability.Specs[i].IncludeAliases = true
164+
}
165+
}
166+
161167
rows, queryErr := dbsearch.FindMatches(reader, dbsearch.AffectedPackagesOptions{
162168
Vulnerability: opts.Vulnerability.Specs,
163169
Package: opts.Package.PkgSpecs,

cmd/grype/cli/commands/db_search_vuln.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ func runDBSearchVulnerabilities(opts dbSearchVulnerabilityOptions) error {
8585
}
8686

8787
rows, err := dbsearch.FindVulnerabilities(reader, dbsearch.VulnerabilitiesOptions{
88-
Vulnerability: opts.Vulnerability.Specs,
89-
RecordLimit: opts.Bounds.RecordLimit,
88+
Vulnerability: opts.Vulnerability.Specs,
89+
RecordLimit: opts.Bounds.RecordLimit,
90+
IncludeAliases: opts.Vulnerability.IncludeAliases,
9091
})
9192
if err != nil {
9293
return err

cmd/grype/cli/commands/internal/dbsearch/affected_packages.go

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ func toOS(os *v6.OperatingSystem) *OperatingSystem {
195195
func FindAffectedPackages(reader interface {
196196
v6.AffectedPackageStoreReader
197197
v6.AffectedCPEStoreReader
198+
v6.UnaffectedPackageStoreReader
199+
v6.UnaffectedCPEStoreReader
198200
v6.VulnerabilityDecoratorStoreReader
199201
}, criteria AffectedPackagesOptions,
200202
) ([]AffectedPackage, error) {
@@ -211,9 +213,11 @@ func FindAffectedPackages(reader interface {
211213
return newAffectedPackageRows(allAffectedPkgs, allAffectedCPEs), nil
212214
}
213215

214-
func findAffectedPackages(reader interface { //nolint:funlen,gocognit
216+
func findAffectedPackages(reader interface { //nolint:funlen,gocognit,gocyclo
215217
v6.AffectedPackageStoreReader
216218
v6.AffectedCPEStoreReader
219+
v6.UnaffectedPackageStoreReader
220+
v6.UnaffectedCPEStoreReader
217221
v6.VulnerabilityDecoratorStoreReader
218222
}, config AffectedPackagesOptions,
219223
) ([]affectedPackageWithDecorations, []affectedCPEWithDecorations, error) {
@@ -286,6 +290,33 @@ func findAffectedPackages(reader interface { //nolint:funlen,gocognit
286290
}
287291
return nil, nil, fmt.Errorf("unable to get affected packages for %s: %w", vulnSpecs, err)
288292
}
293+
294+
unaffectedPkgs, err := reader.GetUnaffectedPackages(pkgSpec, &v6.GetPackageOptions{
295+
PreloadOS: true,
296+
PreloadPackage: true,
297+
PreloadPackageCPEs: false,
298+
PreloadVulnerability: true,
299+
PreloadBlob: true,
300+
OSs: osSpecs,
301+
Vulnerabilities: vulnSpecs,
302+
AllowBroadCPEMatching: config.AllowBroadCPEMatching,
303+
Limit: config.RecordLimit,
304+
})
305+
306+
for i := range unaffectedPkgs {
307+
p := v6.AffectedPackageHandle(unaffectedPkgs[i])
308+
markUnaffected(&p.BlobValue)
309+
allAffectedPkgs = append(allAffectedPkgs, affectedPackageWithDecorations{
310+
AffectedPackageHandle: p,
311+
})
312+
}
313+
314+
if err != nil {
315+
if errors.Is(err, v6.ErrLimitReached) {
316+
return allAffectedPkgs, allAffectedCPEs, err
317+
}
318+
return nil, nil, fmt.Errorf("unable to get unaffected packages for %s: %w", vulnSpecs, err)
319+
}
289320
}
290321

291322
if osSpecs.IsAny() {
@@ -319,8 +350,63 @@ func findAffectedPackages(reader interface { //nolint:funlen,gocognit
319350
}
320351
return nil, nil, fmt.Errorf("unable to get affected cpes for %s: %w", vulnSpecs, err)
321352
}
353+
354+
unaffectedCPEs, err := reader.GetUnaffectedCPEs(searchCPE, &v6.GetCPEOptions{
355+
PreloadCPE: true,
356+
PreloadVulnerability: true,
357+
PreloadBlob: true,
358+
Vulnerabilities: vulnSpecs,
359+
AllowBroadCPEMatching: config.AllowBroadCPEMatching,
360+
Limit: config.RecordLimit,
361+
})
362+
363+
for i := range unaffectedCPEs {
364+
p := v6.AffectedCPEHandle(unaffectedCPEs[i])
365+
if p.BlobValue != nil && len(p.BlobValue.Ranges) > 0 {
366+
for r := range p.BlobValue.Ranges {
367+
p.BlobValue.Ranges[r].Fix.Version += " (unaffected)"
368+
}
369+
} else {
370+
if p.BlobValue == nil {
371+
p.BlobValue = &v6.PackageBlob{}
372+
}
373+
p.BlobValue.Ranges = append(p.BlobValue.Ranges, v6.Range{
374+
Fix: &v6.Fix{
375+
Version: "unaffected",
376+
},
377+
})
378+
}
379+
allAffectedCPEs = append(allAffectedCPEs, affectedCPEWithDecorations{
380+
AffectedCPEHandle: p,
381+
})
382+
}
383+
384+
if err != nil {
385+
if errors.Is(err, v6.ErrLimitReached) {
386+
return allAffectedPkgs, allAffectedCPEs, err
387+
}
388+
return nil, nil, fmt.Errorf("unable to get affected cpes for %s: %w", vulnSpecs, err)
389+
}
322390
}
323391
}
324392

325393
return allAffectedPkgs, allAffectedCPEs, nil
326394
}
395+
396+
func markUnaffected(i **v6.PackageBlob) {
397+
if *i == nil {
398+
*i = &v6.PackageBlob{}
399+
}
400+
b := *i
401+
if len(b.Ranges) > 0 {
402+
for r := range b.Ranges {
403+
b.Ranges[r].Version.Constraint += " (unaffected)"
404+
}
405+
} else {
406+
b.Ranges = append(b.Ranges, v6.Range{
407+
Version: v6.Version{
408+
Constraint: "(unaffected)",
409+
},
410+
})
411+
}
412+
}

0 commit comments

Comments
 (0)