vulncheck: add imports only mode for vuln detection in binaries
Change-Id: I1acd8ca2fe7bf45abb3ada01f40e63ffd909bcee
Reviewed-on: https://go-review.googlesource.com/c/exp/+/382554
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Trust: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/vulncheck/binary.go b/vulncheck/binary.go
index 08ea3f7..eeefd90 100644
--- a/vulncheck/binary.go
+++ b/vulncheck/binary.go
@@ -31,28 +31,70 @@
result := &Result{}
for pkg, symbols := range packageSymbols {
- for _, symbol := range symbols {
- for _, osv := range modVulns.VulnsForSymbol(pkg, symbol) {
- for _, affected := range osv.Affected {
- if affected.Package.Name != pkg {
- continue
- }
- for _, symbol := range affected.EcosystemSpecific.Symbols {
- vuln := &Vuln{
- OSV: osv,
- Symbol: symbol,
- PkgPath: pkg,
- // TODO(zpavlinovic): infer mod path from PkgPath and modules?
- }
- result.Vulns = append(result.Vulns, vuln)
- }
- }
- }
+ if cfg.ImportsOnly {
+ addImportsOnlyVulns(pkg, symbols, result, modVulns)
+ } else {
+ addSymbolVulns(pkg, symbols, result, modVulns)
}
}
return result, nil
}
+// addImportsOnlyVulns adds Vuln entries to result in imports only mode, i.e., for each vulnerable symbol
+// of pkg.
+func addImportsOnlyVulns(pkg string, symbols []string, result *Result, modVulns moduleVulnerabilities) {
+ for _, osv := range modVulns.VulnsForPackage(pkg) {
+ for _, affected := range osv.Affected {
+ if affected.Package.Name != pkg {
+ continue
+ }
+
+ var syms []string
+ if len(affected.EcosystemSpecific.Symbols) == 0 {
+ // If every symbol of pkg is vulnerable, we would ideally compute
+ // every symbol mentioned in the pkg and then add Vuln entry for it,
+ // just as we do in Source. However, we don't have code of pkg here
+ // so we have to do best we can, which is the symbols of pkg actually
+ // appearing in the binary.
+ syms = symbols
+ } else {
+ syms = affected.EcosystemSpecific.Symbols
+ }
+
+ for _, symbol := range syms {
+ vuln := &Vuln{
+ OSV: osv,
+ Symbol: symbol,
+ PkgPath: pkg,
+ // TODO(zpavlinovic): infer mod path from PkgPath and modules?
+ }
+ result.Vulns = append(result.Vulns, vuln)
+ }
+ }
+ }
+}
+
+// addSymbolVulns adds Vuln entries to result for every symbol of pkg in the binary that is vulnerable.
+func addSymbolVulns(pkg string, symbols []string, result *Result, modVulns moduleVulnerabilities) {
+ for _, symbol := range symbols {
+ for _, osv := range modVulns.VulnsForSymbol(pkg, symbol) {
+ for _, affected := range osv.Affected {
+ if affected.Package.Name != pkg {
+ continue
+ }
+ vuln := &Vuln{
+ OSV: osv,
+ Symbol: symbol,
+ PkgPath: pkg,
+ // TODO(zpavlinovic): infer mod path from PkgPath and modules?
+ }
+ result.Vulns = append(result.Vulns, vuln)
+ break
+ }
+ }
+ }
+}
+
func convertModules(mods []*packages.Module) []*Module {
vmods := make([]*Module, len(mods))
// TODO(github.com/golang/go/issues/50030): should we share unique