From a06239cc8bf7b9cee39c57e54a0a056a9fd7c538 Mon Sep 17 00:00:00 2001 From: Zvonimir Pavlinovic Date: Mon, 11 Mar 2024 15:59:27 +0000 Subject: [PATCH] internal/vulncheck: get correctly package for instantiated functions Fixes golang/go#66139 Change-Id: I57812643c78e6cd17415e310567212587978a233 Reviewed-on: https://go-review.googlesource.com/c/vuln/+/570616 LUCI-TryBot-Result: Go LUCI TryBot-Result: Gopher Robot Run-TryBot: Zvonimir Pavlinovic Reviewed-by: Maceo Thompson --- .../testdata/modules/stdlib/stdlib.go | 8 ++++ .../testfiles/stdlib/source_stdlib_json.ct | 42 +++++++++++++++++++ .../testfiles/stdlib/source_stdlib_text.ct | 5 +++ internal/internal.go | 6 ++- internal/vulncheck/source.go | 9 ---- internal/vulncheck/utils.go | 18 +++++++- 6 files changed, 77 insertions(+), 11 deletions(-) diff --git a/cmd/govulncheck/testdata/modules/stdlib/stdlib.go b/cmd/govulncheck/testdata/modules/stdlib/stdlib.go index 2230f427..200c618f 100644 --- a/cmd/govulncheck/testdata/modules/stdlib/stdlib.go +++ b/cmd/govulncheck/testdata/modules/stdlib/stdlib.go @@ -15,4 +15,12 @@ func main() { http.HandleFunc("/hello", helloHandler) log.Fatal(http.ListenAndServe(":8080", nil)) + + // Test issue #66139 + log.Fatal(work[string]("golang")) +} + +func work[T any](t T) error { + log.Printf("%v\n", t) + return http.Serve(nil, nil) } diff --git a/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_json.ct b/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_json.ct index 00fc52b2..87298be9 100644 --- a/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_json.ct +++ b/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_json.ct @@ -185,3 +185,45 @@ $ govulncheck -C ${moddir}/stdlib -format json . ] } } +{ + "finding": { + "osv": "GO-2022-0969", + "fixed_version": "v1.18.6", + "trace": [ + { + "module": "stdlib", + "version": "v1.18.0", + "package": "net/http", + "function": "Serve", + "position": { + "filename": "src/net/http/server.go", + "offset": , + "line": , + "column": + } + }, + { + "module": "golang.org/stdlib", + "package": "golang.org/stdlib", + "function": "work[string]", + "position": { + "filename": "stdlib.go", + "offset": , + "line": , + "column": + } + }, + { + "module": "golang.org/stdlib", + "package": "golang.org/stdlib", + "function": "main", + "position": { + "filename": "stdlib.go", + "offset": , + "line": , + "column": + } + } + ] + } +} diff --git a/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_text.ct b/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_text.ct index 7fa8b284..477c42ba 100644 --- a/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_text.ct +++ b/cmd/govulncheck/testdata/testfiles/stdlib/source_stdlib_text.ct @@ -15,6 +15,7 @@ Vulnerability #1: GO-2022-0969 Fixed in: net/http@go1.18.6 Example traces found: #1: stdlib.go::: stdlib.main calls http.ListenAndServe + #2: stdlib.go::: stdlib.work[string] calls http.Serve Your code is affected by 1 vulnerability from the Go standard library. This scan found no other vulnerabilities in packages you import or modules you @@ -40,6 +41,10 @@ Vulnerability #1: GO-2022-0969 #1: for function net/http.ListenAndServe stdlib.go::: golang.org/stdlib.main src/net/http/server.go::: net/http.ListenAndServe + #2: for function net/http.Serve + stdlib.go::: golang.org/stdlib.main + stdlib.go::: golang.org/stdlib.work[string] + src/net/http/server.go::: net/http.Serve Your code is affected by 1 vulnerability from the Go standard library. This scan found no other vulnerabilities in packages you import or modules you diff --git a/internal/internal.go b/internal/internal.go index 64c5e8d5..8e6b7f5c 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -24,5 +24,9 @@ const ( // UnknownModulePath is a special module path for when we cannot work out // the module for a package. - UnknownModulePath = "unknown" + UnknownModulePath = "unknown-module" + + // UnknownPackagePath is a special package path for when we cannot work out + // the packagUnknownModulePath = "unknown" + UnknownPackagePath = "unknown-package" ) diff --git a/internal/vulncheck/source.go b/internal/vulncheck/source.go index 92517bb7..4014eff7 100644 --- a/internal/vulncheck/source.go +++ b/internal/vulncheck/source.go @@ -275,15 +275,6 @@ func vulnFuncs(cg *callgraph.Graph, affVulns affectingVulns) map[*callgraph.Node return m } -// pkgPath returns the path of the f's enclosing package, if any. -// Otherwise, returns "". -func pkgPath(f *ssa.Function) string { - if f.Package() != nil && f.Package().Pkg != nil { - return f.Package().Pkg.Path() - } - return "" -} - func createNode(nodes map[*ssa.Function]*FuncNode, f *ssa.Function, graph *PackageGraph) *FuncNode { if fn, ok := nodes[f]; ok { return fn diff --git a/internal/vulncheck/utils.go b/internal/vulncheck/utils.go index fb081455..9e3e546c 100644 --- a/internal/vulncheck/utils.go +++ b/internal/vulncheck/utils.go @@ -18,6 +18,7 @@ import ( "golang.org/x/tools/go/packages" "golang.org/x/tools/go/ssa/ssautil" "golang.org/x/tools/go/types/typeutil" + "golang.org/x/vuln/internal" "golang.org/x/vuln/internal/osv" "golang.org/x/vuln/internal/semver" @@ -348,8 +349,23 @@ func modVersion(mod *packages.Module) string { return mod.Version } +// pkgPath returns the path of the f's enclosing package, if any. +// Otherwise, returns internal.UnknownPackagePath. +func pkgPath(f *ssa.Function) string { + g := f + if f.Origin() != nil { + // Instantiations of generics do not have + // an associated package. We hence look up + // the original function for the package. + g = f.Origin() + } + if g.Package() != nil && g.Package().Pkg != nil { + return g.Package().Pkg.Path() + } + return internal.UnknownPackagePath +} func IsStdPackage(pkg string) bool { - if pkg == "" { + if pkg == "" || pkg == internal.UnknownPackagePath { return false } // std packages do not have a "." in their path. For instance, see