exp,internal/govulncheck: add govulncheck API
An API is defined for internal/govulncheck.
The API in exp/govulncheck is updated to use internal/govulncheck.Config
and internal/govulncheck.Source.
For golang/go#56042
Change-Id: Ibab2fae0685166e7712b355e2c7c2ab0b4d50c6c
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/440219
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Julie Qiu <julie@golang.org>
diff --git a/exp/govulncheck/govulncheck.go b/exp/govulncheck/govulncheck.go
index 12fa6b6..ee36839 100644
--- a/exp/govulncheck/govulncheck.go
+++ b/exp/govulncheck/govulncheck.go
@@ -2,21 +2,35 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package govulncheck has experimental govulncheck API.
+// Package govulncheck provides an experimental govulncheck API.
package govulncheck
-import (
- "context"
+import "golang.org/x/vuln/internal/govulncheck"
- "golang.org/x/vuln/internal/govulncheck"
+// Source reports vulnerabilities that affect the analyzed packages.
+var Source = govulncheck.Source
+
+type (
+ // Config is the configuration for Main.
+ Config = govulncheck.Config
+
+ // Result is the result of executing Source.
+ Result = govulncheck.Result
+
+ // Vuln represents a single OSV entry.
+ Vuln = govulncheck.Vuln
+
+ // Module represents a specific vulnerability relevant to a
+ // single module or package.
+ Module = govulncheck.Module
+
+ // Package is a Go package with known vulnerable symbols.
+ Package = govulncheck.Package
+
+ // CallStacks contains a representative call stack for each
+ // vulnerable symbol that is called.
+ CallStack = govulncheck.CallStack
+
+ // StackFrame represents a call stack entry.
+ StackFrame = govulncheck.StackFrame
)
-
-// Config is the configuration for Main.
-type Config = govulncheck.LegacyConfig
-
-// Main is the main function for the govulncheck command line tool.
-func Main(cfg Config) error {
- ctx := context.Background()
- _, err := govulncheck.LegacyRun(ctx, cfg)
- return err
-}
diff --git a/internal/govulncheck/cache.go b/internal/govulncheck/cache.go
index 5ce73e4..922a694 100644
--- a/internal/govulncheck/cache.go
+++ b/internal/govulncheck/cache.go
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package govulncheck supports the govulncheck command.
package govulncheck
import (
diff --git a/internal/govulncheck/result.go b/internal/govulncheck/result.go
index 16b2359..f6916f7 100644
--- a/internal/govulncheck/result.go
+++ b/internal/govulncheck/result.go
@@ -1,10 +1,153 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+
+// Package govulncheck provides functionality to support the govulncheck command.
package govulncheck
-// Result is contains output information for govulncheck.
-//
-// TODO(https://go.dev/issue/56042): this API is a work in progress.
+import (
+ "go/token"
+
+ "golang.org/x/tools/go/packages"
+ "golang.org/x/vuln/client"
+ "golang.org/x/vuln/osv"
+)
+
+// LoadMode is the level of information needed for each package
+// for running golang.org/x/tools/go/packages.Load.
+var LoadMode = packages.NeedName | packages.NeedImports | packages.NeedTypes |
+ packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps |
+ packages.NeedModule
+
+// Config is used for configuring the output of govulncheck.
+type Config struct {
+ // Client is the client used to make requests to a vulnerability
+ // database(s). If nil, a default client is constructed that makes requests
+ // to vuln.go.dev.
+ Client client.Client
+
+ // GoVersion specifies the Go version used when analyzing source code.
+ //
+ // By default, GoVersion is the go command version found from the PATH.
+ GoVersion string
+
+ // Verbosity controls the stdout and stderr output when running Source.
+ //
+ // TODO(https://go.dev/issue/56042): make this an enum.
+ Verbosity string
+}
+
+// Result is the result of executing Source or Binary.
type Result struct {
+ // Vulns contains all vulnerabilities that are called or imported by
+ // the analyzed module.
+ Vulns []*Vuln
+}
+
+// Vuln represents a single OSV entry.
+type Vuln struct {
+ // OSV contains all data from the OSV entry for this vulnerability.
+ OSV *osv.Entry
+
+ // Modules contains all of the modules in the OSV entry where a
+ // vulnerable package is imported by the target source code or binary.
+ //
+ // For example, a module M with two packages M/p1 and M/p2, where only p1
+ // is vulnerable, will appear in this list if and only if p1 is imported by
+ // the target source code or binary.
+ Modules []*Module
+}
+
+// IsCalled reports whether the vulnerability is called, therefore
+// affecting the target source code or binary.
+//
+// TODO(https://go.dev/issue/56042): implement
+func (v *Vuln) IsCalled() bool {
+ return false
+}
+
+// Module represents a specific vulnerability relevant to a single module.
+type Module struct {
+ // Path is the module path of the module containing the vulnerability.
+ //
+ // Importable packages in the standard library will have the path "stdlib".
+ Path string
+
+ // FoundVersion is the module version where the vulnerability was found.
+ FoundVersion string
+
+ // FixedVersion is the module version where the vulnerability was
+ // fixed. If there are multiple fixed versions in the OSV report, this will
+ // be the latest fixed version.
+ //
+ // This is empty if a fix is not available.
+ FixedVersion string
+
+ // Packages contains all the vulnerable packages in OSV entry that are
+ // imported by the target source code or binary.
+ //
+ // For example, given a module M with two packages M/p1 and M/p2, where
+ // both p1 and p2 are vulnerable, p1 and p2 will each only appear in this
+ // list they are individually imported by the target source code or binary.
+ Packages []*Package
+}
+
+// Package is a Go package with known vulnerable symbols.
+type Package struct {
+ // Path is the import path of the package containing the vulnerability.
+ Path string
+
+ // CallStacks contains a representative call stack for each
+ // vulnerable symbol that is called.
+ //
+ // For vulnerabilities found from binary analysis, only CallStack.Symbol
+ // will be provided.
+ //
+ // For non-affecting vulnerabilities reported from the source mode
+ // analysis, this will be empty.
+ CallStacks []CallStack
+}
+
+// CallStacks contains a representative call stack for a vulnerable
+// symbol.
+type CallStack struct {
+ // Symbol is the name of the detected vulnerable function
+ // or method.
+ //
+ // This follows the naming convention in the OSV report.
+ Symbol string
+
+ // Summary is a one-line description of the callstack, used by the
+ // default govulncheck mode.
+ //
+ // Example: module3.main calls github.com/shiyanhui/dht.DHT.Run
+ Summary string
+
+ // Frames contains an entry for each stack in the call stack.
+ //
+ // Frames are sorted starting from the entry point to the
+ // imported vulnerable symbol. The last frame in Frames should match
+ // Symbol.
+ Frames []*StackFrame
+}
+
+// StackFrame represents a call stack entry.
+type StackFrame struct {
+ // PackagePath is the import path.
+ PkgPath string
+
+ // FuncName is the function name.
+ FuncName string
+
+ // RecvName is the receiver name, if the symbol is a
+ // method.
+ //
+ // The client can create the final symbol name by
+ // prepending RecvName to FuncName.
+ RecvName string
+
+ // Position describes an arbitrary source position
+ // including the file, line, and column location.
+ // A Position is valid if the line number is > 0.
+ Position token.Position
}
diff --git a/internal/govulncheck/run.go b/internal/govulncheck/run.go
new file mode 100644
index 0000000..927f770
--- /dev/null
+++ b/internal/govulncheck/run.go
@@ -0,0 +1,36 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package govulncheck
+
+import (
+ "context"
+ "errors"
+ "io"
+
+ "golang.org/x/vuln/vulncheck"
+)
+
+// Source reports vulnerabilities that affect the analyzed packages.
+//
+// Vulnerabilities can be called (affecting the package, because a vulnerable
+// symbol is actually exercised) or just imported by the package
+// (likely having a non-affecting outcome).
+//
+// This function is used for source code analysis by cmd/govulncheck and
+// exp/govulncheck.
+//
+// TODO(https://go.dev/issue/56042): implement
+func Source(ctx context.Context, cfg *Config, pkgs []*vulncheck.Package) (*Result, error) {
+ return nil, errors.New("not implemented")
+}
+
+// Binary detects presence of vulnerable symbols in exe.
+//
+// This function is used for binary analysis by cmd/govulncheck.
+//
+// TODO(https://go.dev/issue/56042): implement
+func Binary(ctx context.Context, cfg *Config, exe io.ReaderAt) (*Result, error) {
+ return nil, errors.New("not implemented")
+}