Hyang-Ah Hana Kim submitted this change.
gopls/internal/govulncheck: sync x/vuln@62b0186
VulnDB OSV schema was changed recently
https://go-review.googlesource.com/c/vulndb/+/424895
to fix the misinterpretation of 'affected.package.name',
and the database entries were repopulated with the new schema.
We need to update the client library to pick up the change.
We also need to update the fake vulndb entries used in tests.
gopls/regtest/misc/testdata/vulndb was copied from
golang.org/x/vuln/cmd/govulncheck/testdata/vulndb @ 62b0186
(the version updated in cl/424895)
Also reverse golang.org/cl/425183 which includes the position
information in the SummarizeCallStack result. Like in govulncheck -v,
the position info is already available in the callstack, thus
this is unnecessary for us. Since x/vuln is currently frozen
until the preview release, revert it from gopls/internal/vulncheck.
Ran go mod tidy -compat=1.16; otherwise, the transitive dependency
on github.com/client9/misspell from golang.org/x/vuln breaks go1.16
build.
Updated copy.sh script to copy x/vuln/internal/semver package
(golang/go#54401) and add the build tags back to all go files.
Gopls's builder builds&tests packages with old go versions,
so we still need go1.18 build tag.
Fixes golang/go#54818
Change-Id: I37770d698082378656a7988d3412a4ca2196ca7b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/427542
gopls-CI: kokoro <noreply...@google.com>
Run-TryBot: Hyang-Ah Hana Kim <hya...@gmail.com>
TryBot-Result: Gopher Robot <go...@golang.org>
Reviewed-by: Jonathan Amsterdam <j...@google.com>
---
M gopls/go.mod
M gopls/go.sum
M gopls/internal/govulncheck/cache.go
M gopls/internal/govulncheck/cache_test.go
M gopls/internal/govulncheck/copy.sh
A gopls/internal/govulncheck/filepath.go
A gopls/internal/govulncheck/filepath_test.go
A gopls/internal/govulncheck/semver/semver.go
A gopls/internal/govulncheck/semver/semver_test.go
M gopls/internal/govulncheck/source.go
M gopls/internal/govulncheck/util.go
M gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/crypto.json
M gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/text.json
M gopls/internal/regtest/misc/testdata/vulndb/stdlib.json
M gopls/internal/regtest/misc/vuln_test.go
M gopls/internal/vulncheck/command.go
M gopls/internal/vulncheck/command_test.go
17 files changed, 355 insertions(+), 32 deletions(-)
diff --git a/gopls/go.mod b/gopls/go.mod
index 49f5804..d994f48 100644
--- a/gopls/go.mod
+++ b/gopls/go.mod
@@ -10,12 +10,14 @@
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664
golang.org/x/tools v0.1.13-0.20220810174125-0ad49fdeb955
- golang.org/x/vuln v0.0.0-20220809164104-12ff722659c1
+ golang.org/x/vuln v0.0.0-20220901221904-62b0186a1058
honnef.co/go/tools v0.3.3
mvdan.cc/gofumpt v0.3.1
mvdan.cc/xurls/v2 v2.4.0
)
+require golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
+
require (
github.com/BurntSushi/toml v1.2.0 // indirect
github.com/google/safehtml v0.0.2 // indirect
diff --git a/gopls/go.sum b/gopls/go.sum
index 2b9d615..f647316 100644
--- a/gopls/go.sum
+++ b/gopls/go.sum
@@ -12,7 +12,6 @@
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/google/go-cmdtest v0.4.0/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -43,6 +42,8 @@
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20220722155223-a9213eeb770e h1:7Xs2YCOpMlNqSQSmrrnhlzBXIE/bpMecZplbLePTJvE=
golang.org/x/exp/typeparams v0.0.0-20220722155223-a9213eeb770e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
@@ -68,8 +69,8 @@
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/vuln v0.0.0-20220809164104-12ff722659c1 h1:wxIK8Hnmd3ervTxk4aON+gAbfWbb2hToeKSTQd0eXgo=
-golang.org/x/vuln v0.0.0-20220809164104-12ff722659c1/go.mod h1:t0tyWMAuNGUOL2N4il/aj/M5LLt4ktPpOGuTBNUqmiM=
+golang.org/x/vuln v0.0.0-20220901221904-62b0186a1058 h1:YnB27EXBD8XxB0JcaOeluuvhF2kS4DrH0k+lpopG2xc=
+golang.org/x/vuln v0.0.0-20220901221904-62b0186a1058/go.mod h1:7tDfEDtOLlzHQRi4Yzfg5seVBSvouUIjyPzBx4q5CxQ=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/gopls/internal/govulncheck/cache.go b/gopls/internal/govulncheck/cache.go
index 404c356..2fa6a05 100644
--- a/gopls/internal/govulncheck/cache.go
+++ b/gopls/internal/govulncheck/cache.go
@@ -11,7 +11,6 @@
import (
"encoding/json"
"go/build"
- "io/ioutil"
"os"
"path/filepath"
"sync"
@@ -66,7 +65,7 @@
c.mu.Lock()
defer c.mu.Unlock()
- b, err := ioutil.ReadFile(filepath.Join(c.rootDir, dbName, "index.json"))
+ b, err := os.ReadFile(filepath.Join(c.rootDir, dbName, "index.json"))
if err != nil {
if os.IsNotExist(err) {
return nil, time.Time{}, nil
@@ -95,7 +94,7 @@
if err != nil {
return err
}
- if err := ioutil.WriteFile(filepath.Join(path, "index.json"), j, 0666); err != nil {
+ if err := os.WriteFile(filepath.Join(path, "index.json"), j, 0666); err != nil {
return err
}
return nil
@@ -105,7 +104,11 @@
c.mu.Lock()
defer c.mu.Unlock()
- b, err := ioutil.ReadFile(filepath.Join(c.rootDir, dbName, p, "vulns.json"))
+ ep, err := client.EscapeModulePath(p)
+ if err != nil {
+ return nil, err
+ }
+ b, err := os.ReadFile(filepath.Join(c.rootDir, dbName, ep, "vulns.json"))
if err != nil {
if os.IsNotExist(err) {
return nil, nil
@@ -123,7 +126,11 @@
c.mu.Lock()
defer c.mu.Unlock()
- path := filepath.Join(c.rootDir, dbName, p)
+ ep, err := client.EscapeModulePath(p)
+ if err != nil {
+ return err
+ }
+ path := filepath.Join(c.rootDir, dbName, ep)
if err := os.MkdirAll(path, 0777); err != nil {
return err
}
@@ -131,7 +138,7 @@
if err != nil {
return err
}
- if err := ioutil.WriteFile(filepath.Join(path, "vulns.json"), j, 0666); err != nil {
+ if err := os.WriteFile(filepath.Join(path, "vulns.json"), j, 0666); err != nil {
return err
}
return nil
diff --git a/gopls/internal/govulncheck/cache_test.go b/gopls/internal/govulncheck/cache_test.go
index 5a25c78..57e8765 100644
--- a/gopls/internal/govulncheck/cache_test.go
+++ b/gopls/internal/govulncheck/cache_test.go
@@ -93,7 +93,7 @@
i := i
g.Go(func() error {
id := i % 5
- p := fmt.Sprintf("package%d", id)
+ p := fmt.Sprintf("example.com/package%d", id)
entries, err := cache.ReadEntries(dbName, p)
if err != nil {
@@ -115,7 +115,7 @@
// sanity checking
for i := 0; i < 5; i++ {
id := fmt.Sprint(i)
- p := fmt.Sprintf("package%s", id)
+ p := fmt.Sprintf("example.com/package%s", id)
es, err := cache.ReadEntries(dbName, p)
if err != nil {
diff --git a/gopls/internal/govulncheck/copy.sh b/gopls/internal/govulncheck/copy.sh
index 24ed45b..398cde2 100755
--- a/gopls/internal/govulncheck/copy.sh
+++ b/gopls/internal/govulncheck/copy.sh
@@ -11,3 +11,22 @@
rm -f *.go
cp ../../../../vuln/cmd/govulncheck/internal/govulncheck/*.go .
+
+sed -i '' 's/\"golang.org\/x\/vuln\/internal\/semver\"/\"golang.org\/x\/tools\/gopls\/internal\/govulncheck\/semver\"/g' *.go
+sed -i '' -e '4 i\
+' -e '4 i\
+//go:build go1.18' -e '4 i\
+// +build go1.18' *.go
+
+# Copy golang.org/x/vuln/internal/semver that
+# golang.org/x/vuln/cmd/govulncheck/internal/govulncheck
+# depends on.
+
+mkdir -p semver
+cd semver
+rm -f *.go
+cp ../../../../../vuln/internal/semver/*.go .
+sed -i '' -e '4 i\
+' -e '4 i\
+//go:build go1.18' -e '4 i\
+// +build go1.18' *.go
diff --git a/gopls/internal/govulncheck/filepath.go b/gopls/internal/govulncheck/filepath.go
new file mode 100644
index 0000000..cef78f5
--- /dev/null
+++ b/gopls/internal/govulncheck/filepath.go
@@ -0,0 +1,38 @@
+// 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.
+
+//go:build go1.18
+// +build go1.18
+
+package govulncheck
+
+import (
+ "path/filepath"
+ "strings"
+)
+
+// AbsRelShorter takes path and returns its path relative
+// to the current directory, if shorter. Returns path
+// when path is an empty string or upon any error.
+func AbsRelShorter(path string) string {
+ if path == "" {
+ return ""
+ }
+
+ c, err := filepath.Abs(".")
+ if err != nil {
+ return path
+ }
+ r, err := filepath.Rel(c, path)
+ if err != nil {
+ return path
+ }
+
+ rSegments := strings.Split(r, string(filepath.Separator))
+ pathSegments := strings.Split(path, string(filepath.Separator))
+ if len(rSegments) < len(pathSegments) {
+ return r
+ }
+ return path
+}
diff --git a/gopls/internal/govulncheck/filepath_test.go b/gopls/internal/govulncheck/filepath_test.go
new file mode 100644
index 0000000..06ef40a
--- /dev/null
+++ b/gopls/internal/govulncheck/filepath_test.go
@@ -0,0 +1,42 @@
+// 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.
+
+//go:build go1.18
+// +build go1.18
+
+package govulncheck
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+func TestAbsRelShorter(t *testing.T) {
+ thisFile := "filepath_test.go"
+ thisFileAbs, _ := filepath.Abs(thisFile)
+
+ tf, err := os.CreateTemp("", "filepath_test.gp")
+ if err != nil {
+ t.Errorf("could not create temporary filepath_test.go file: %v", err)
+ }
+ tempFile := tf.Name()
+ tempFileAbs, _ := filepath.Abs(tempFile)
+
+ for _, test := range []struct {
+ l string
+ want string
+ }{
+ {thisFile, "filepath_test.go"},
+ {thisFileAbs, "filepath_test.go"},
+ // Relative path to temp file from "." is longer as
+ // it needs to go back the length of the absolute
+ // path and then in addition go to os.TempDir.
+ {tempFile, tempFileAbs},
+ } {
+ if got := AbsRelShorter(test.l); got != test.want {
+ t.Errorf("want %s; got %s", test.want, got)
+ }
+ }
+}
diff --git a/gopls/internal/govulncheck/semver/semver.go b/gopls/internal/govulncheck/semver/semver.go
new file mode 100644
index 0000000..8b1cfe5
--- /dev/null
+++ b/gopls/internal/govulncheck/semver/semver.go
@@ -0,0 +1,84 @@
+// 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.
+
+//go:build go1.18
+// +build go1.18
+
+// Package semver provides shared utilities for manipulating
+// Go semantic versions.
+package semver
+
+import (
+ "regexp"
+ "strings"
+)
+
+// addSemverPrefix adds a 'v' prefix to s if it isn't already prefixed
+// with 'v' or 'go'. This allows us to easily test go-style SEMVER
+// strings against normal SEMVER strings.
+func addSemverPrefix(s string) string {
+ if !strings.HasPrefix(s, "v") && !strings.HasPrefix(s, "go") {
+ return "v" + s
+ }
+ return s
+}
+
+// removeSemverPrefix removes the 'v' or 'go' prefixes from go-style
+// SEMVER strings, for usage in the public vulnerability format.
+func removeSemverPrefix(s string) string {
+ s = strings.TrimPrefix(s, "v")
+ s = strings.TrimPrefix(s, "go")
+ return s
+}
+
+// CanonicalizeSemverPrefix turns a SEMVER string into the canonical
+// representation using the 'v' prefix, as used by the OSV format.
+// Input may be a bare SEMVER ("1.2.3"), Go prefixed SEMVER ("go1.2.3"),
+// or already canonical SEMVER ("v1.2.3").
+func CanonicalizeSemverPrefix(s string) string {
+ return addSemverPrefix(removeSemverPrefix(s))
+}
+
+var (
+ // Regexp for matching go tags. The groups are:
+ // 1 the major.minor version
+ // 2 the patch version, or empty if none
+ // 3 the entire prerelease, if present
+ // 4 the prerelease type ("beta" or "rc")
+ // 5 the prerelease number
+ tagRegexp = regexp.MustCompile(`^go(\d+\.\d+)(\.\d+|)((beta|rc|-pre)(\d+))?$`)
+)
+
+// This is a modified copy of pkgsite/internal/stdlib:VersionForTag.
+func GoTagToSemver(tag string) string {
+ if tag == "" {
+ return ""
+ }
+
+ tag = strings.Fields(tag)[0]
+ // Special cases for go1.
+ if tag == "go1" {
+ return "v1.0.0"
+ }
+ if tag == "go1.0" {
+ return ""
+ }
+ m := tagRegexp.FindStringSubmatch(tag)
+ if m == nil {
+ return ""
+ }
+ version := "v" + m[1]
+ if m[2] != "" {
+ version += m[2]
+ } else {
+ version += ".0"
+ }
+ if m[3] != "" {
+ if !strings.HasPrefix(m[4], "-") {
+ version += "-"
+ }
+ version += m[4] + "." + m[5]
+ }
+ return version
+}
diff --git a/gopls/internal/govulncheck/semver/semver_test.go b/gopls/internal/govulncheck/semver/semver_test.go
new file mode 100644
index 0000000..56b6ea8
--- /dev/null
+++ b/gopls/internal/govulncheck/semver/semver_test.go
@@ -0,0 +1,43 @@
+// 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.
+
+//go:build go1.18
+// +build go1.18
+
+package semver
+
+import (
+ "testing"
+)
+
+func TestCanonicalize(t *testing.T) {
+ for _, test := range []struct {
+ v string
+ want string
+ }{
+ {"v1.2.3", "v1.2.3"},
+ {"1.2.3", "v1.2.3"},
+ {"go1.2.3", "v1.2.3"},
+ } {
+ got := CanonicalizeSemverPrefix(test.v)
+ if got != test.want {
+ t.Errorf("want %s; got %s", test.want, got)
+ }
+ }
+}
+
+func TestGoTagToSemver(t *testing.T) {
+ for _, test := range []struct {
+ v string
+ want string
+ }{
+ {"go1.19", "v1.19.0"},
+ {"go1.20-pre4", "v1.20.0-pre.4"},
+ } {
+ got := GoTagToSemver(test.v)
+ if got != test.want {
+ t.Errorf("want %s; got %s", test.want, got)
+ }
+ }
+}
diff --git a/gopls/internal/govulncheck/source.go b/gopls/internal/govulncheck/source.go
index d51fe8c..d3f519d 100644
--- a/gopls/internal/govulncheck/source.go
+++ b/gopls/internal/govulncheck/source.go
@@ -25,7 +25,7 @@
var b strings.Builder
fmt.Fprintln(&b, "Packages contain errors:")
for _, e := range e.Errors {
- fmt.Println(&b, e)
+ fmt.Fprintln(&b, e)
}
return b.String()
}
diff --git a/gopls/internal/govulncheck/util.go b/gopls/internal/govulncheck/util.go
index baa2d96..fc63d56 100644
--- a/gopls/internal/govulncheck/util.go
+++ b/gopls/internal/govulncheck/util.go
@@ -12,6 +12,7 @@
"strings"
"golang.org/x/mod/semver"
+ isem "golang.org/x/tools/gopls/internal/govulncheck/semver"
"golang.org/x/vuln/osv"
"golang.org/x/vuln/vulncheck"
)
@@ -24,7 +25,8 @@
for _, r := range a.Ranges {
if r.Type == osv.TypeSemver {
for _, e := range r.Events {
- if e.Fixed != "" && (v == "" || semver.Compare(e.Fixed, v) > 0) {
+ if e.Fixed != "" && (v == "" ||
+ semver.Compare(isem.CanonicalizeSemverPrefix(e.Fixed), isem.CanonicalizeSemverPrefix(v)) > 0) {
v = e.Fixed
}
}
@@ -60,12 +62,16 @@
}
iVuln += iTop + 1 // adjust for slice in call to highest.
topName := FuncName(cs[iTop].Function)
+ topPos := AbsRelShorter(FuncPos(cs[iTop].Call))
+ if topPos != "" {
+ topPos += ": "
+ }
vulnName := FuncName(cs[iVuln].Function)
if iVuln == iTop+1 {
- return fmt.Sprintf("%s calls %s", topName, vulnName)
+ return fmt.Sprintf("%s%s calls %s", topPos, topName, vulnName)
}
- return fmt.Sprintf("%s calls %s, which eventually calls %s",
- topName, FuncName(cs[iTop+1].Function), vulnName)
+ return fmt.Sprintf("%s%s calls %s, which eventually calls %s",
+ topPos, topName, FuncName(cs[iTop+1].Function), vulnName)
}
// highest returns the highest (one with the smallest index) entry in the call
@@ -107,3 +113,11 @@
func FuncName(fn *vulncheck.FuncNode) string {
return strings.TrimPrefix(fn.String(), "*")
}
+
+// FuncPos returns the function position from call.
+func FuncPos(call *vulncheck.CallSite) string {
+ if call != nil && call.Pos != nil {
+ return call.Pos.String()
+ }
+ return ""
+}
diff --git a/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/crypto.json b/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/crypto.json
index e0a2791..7af60bb 100644
--- a/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/crypto.json
+++ b/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/crypto.json
@@ -1 +1 @@
-[{"id":"GO-2020-0012","published":"2021-04-14T20:04:52Z","modified":"2021-04-14T20:04:52Z","aliases":["CVE-2020-9283"],"details":"An attacker can craft an ssh-ed25519 or sk-ssh-...@openssh.com public\nkey, such that the library will panic when trying to verify a signature\nwith it. If verifying signatures using user supplied public keys, this\nmay be used as a denial of service vector.\n","affected":[{"package":{"name":"golang.org/x/crypto/ssh","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20200220183623-bac4c82f6975"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0012"},"ecosystem_specific":{"symbols":["parseED25519","ed25519PublicKey.Verify","parseSKEd25519","skEd25519PublicKey.Verify","NewPublicKey"]}}],"references":[{"type":"FIX","url":"https://go-review.googlesource.com/c/crypto/+/220357"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/bac4c82f69751a6dd76e702d54b3ceb88adab236"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/3L45YRc91SY"}]},{"id":"GO-2020-0013","published":"2021-04-14T20:04:52Z","modified":"2021-04-14T20:04:52Z","aliases":["CVE-2017-3204"],"details":"By default host key verification is disabled which allows for\nman-in-the-middle attacks against SSH clients if\nClientConfig.HostKeyCallback is not set.\n","affected":[{"package":{"name":"golang.org/x/crypto/ssh","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20170330155735-e4e2799dd7aa"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0013"},"ecosystem_specific":{"symbols":["NewClientConn"]}}],"references":[{"type":"FIX","url":"https://go-review.googlesource.com/38701"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/e4e2799dd7aab89f583e1d898300d96367750991"},{"type":"WEB","url":"https://go.dev/issue/19767"},{"type":"WEB","url":"https://bridge.grumpy-troll.org/2017/04/golang-ssh-security/"}]},{"id":"GO-2021-0227","published":"2022-02-17T17:35:32Z","modified":"2022-02-17T17:35:32Z","aliases":["CVE-2020-29652"],"details":"Clients can cause a panic in SSH servers. An attacker can craft\nan authentication request message for the “gssapi-with-mic” method\nwhich will cause NewServerConn to panic via a nil pointer dereference\nif ServerConfig.GSSAPIWithMICConfig is nil.\n","affected":[{"package":{"name":"golang.org/x/crypto/ssh","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20201216223049-8b5274cf687f"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0227"},"ecosystem_specific":{"symbols":["connection.serverAuthenticate"]}}],"references":[{"type":"FIX","url":"https://go-review.googlesource.com/c/crypto/+/278852"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/8b5274cf687fd9316b4108863654cc57385531e8"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/ouZIlBimOsE?pli=1"}]}]
\ No newline at end of file
+[{"id":"GO-2020-0012","published":"2021-04-14T20:04:52Z","modified":"2021-04-14T20:04:52Z","aliases":["CVE-2020-9283","GHSA-ffhg-7mh4-33c4"],"details":"An attacker can craft an ssh-ed25519 or sk-ssh-...@openssh.com public\nkey, such that the library will panic when trying to verify a signature\nwith it. If verifying signatures using user supplied public keys, this\nmay be used as a denial of service vector.\n","affected":[{"package":{"name":"golang.org/x/crypto","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20200220183623-bac4c82f6975"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0012"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/crypto/ssh","symbols":["NewPublicKey","ed25519PublicKey.Verify","parseED25519","parseSKEd25519","skEd25519PublicKey.Verify"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/220357"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/bac4c82f69751a6dd76e702d54b3ceb88adab236"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/3L45YRc91SY"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2020-9283"},{"type":"WEB","url":"https://github.com/advisories/GHSA-ffhg-7mh4-33c4"}]},{"id":"GO-2020-0013","published":"2021-04-14T20:04:52Z","modified":"2021-04-14T20:04:52Z","aliases":["CVE-2017-3204"],"details":"By default host key verification is disabled which allows for\nman-in-the-middle attacks against SSH clients if\nClientConfig.HostKeyCallback is not set.\n","affected":[{"package":{"name":"golang.org/x/crypto","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20170330155735-e4e2799dd7aa"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0013"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/crypto/ssh","symbols":["NewClientConn"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/340830"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/e4e2799dd7aab89f583e1d898300d96367750991"},{"type":"WEB","url":"https://go.dev/issue/19767"},{"type":"WEB","url":"https://bridge.grumpy-troll.org/2017/04/golang-ssh-security/"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2017-3204"}]},{"id":"GO-2021-0227","published":"2022-02-17T17:35:32Z","modified":"2022-02-17T17:35:32Z","aliases":["CVE-2020-29652"],"details":"Clients can cause a panic in SSH servers. An attacker can craft\nan authentication request message for the “gssapi-with-mic” method\nwhich will cause NewServerConn to panic via a nil pointer dereference\nif ServerConfig.GSSAPIWithMICConfig is nil.\n","affected":[{"package":{"name":"golang.org/x/crypto","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20201216223049-8b5274cf687f"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0227"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/crypto/ssh","symbols":["connection.serverAuthenticate"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/278852"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/8b5274cf687fd9316b4108863654cc57385531e8"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/ouZIlBimOsE?pli=1"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2020-29652"}]},{"id":"GO-2021-0356","published":"2022-04-25T20:38:40Z","modified":"2022-08-18T20:22:13Z","aliases":["CVE-2022-27191","GHSA-8c26-wmh5-6g9v"],"details":"Attackers can cause a crash in SSH servers when the server has been\nconfigured by passing a Signer to ServerConfig.AddHostKey such that\n 1) the Signer passed to AddHostKey does not implement AlgorithmSigner, and\n 2) the Signer passed to AddHostKey returns a key of type “ssh-rsa” from its\n PublicKey method.\n\nServers that only use Signer implementations provided by the ssh package are\nunaffected.\n","affected":[{"package":{"name":"golang.org/x/crypto","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20220314234659-1baeb1ce4c0b"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0356"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/crypto/ssh","symbols":["ServerConfig.AddHostKey","ServerConfig.AddHostKey"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/392355"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/1baeb1ce4c0b006eff0f294c47cb7617598dfb3d"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/-cp44ypCT5s"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2022-27191"},{"type":"WEB","url":"https://github.com/advisories/GHSA-8c26-wmh5-6g9v"}]},{"id":"GO-2022-0209","published":"2022-07-01T20:15:25Z","modified":"2022-08-18T20:22:13Z","aliases":["CVE-2019-11840"],"details":"XORKeyStream generates incorrect and insecure output for very\nlarge inputs.\n\nIf more than 256 GiB of keystream is generated, or if the counter\notherwise grows greater than 32 bits, the amd64 implementation will\nfirst generate incorrect output, and then cycle back to previously\ngenerated keystream. Repeated keystream bytes can lead to loss of\nconfidentiality in encryption applications, or to predictability\nin CSPRNG applications.\n\nThe issue might affect uses of golang.org/x/crypto/nacl with extremely\nlarge messages.\n\nArchitectures other than amd64 and uses that generate less than 256 GiB\nof keystream for a single salsa20.XORKeyStream invocation are unaffected.\n","affected":[{"package":{"name":"golang.org/x/crypto","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20190320223903-b7391e95e576"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2022-0209"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/crypto/salsa20/salsa","goarch":["amd64"],"symbols":["XORKeyStream"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/168406"},{"type":"FIX","url":"https://go.googlesource.com/crypto/+/b7391e95e576cacdcdd422573063bc057239113d"},{"type":"WEB","url":"https://go.dev/issue/30965"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/tjyNcJxb2vQ/m/n0NRBziSCAAJ"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2019-11840"}]},{"id":"GO-2022-0229","published":"2022-07-06T18:23:48Z","modified":"2022-08-18T20:22:13Z","aliases":["CVE-2020-7919","GHSA-cjjc-xp8v-855w"],"details":"On 32-bit architectures, a malformed input to crypto/x509 or\nthe ASN.1 parsing functions of golang.org/x/crypto/cryptobyte\ncan lead to a panic.\n\nThe malformed certificate can be delivered via a crypto/tls\nconnection to a client, or to a server that accepts client\ncertificates. net/http clients can be made to crash by an HTTPS\nserver, while net/http servers that accept client certificates\nwill recover the panic and are unaffected.\n","affected":[{"package":{"name":"stdlib","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.12.16"},{"introduced":"1.13.0"},{"fixed":"1.13.7"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2022-0229"},"ecosystem_specific":{"imports":[{"path":"crypto/x509"}]}},{"package":{"name":"golang.org/x/crypto","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20200124225646-8b5121be2f68"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2022-0229"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/crypto/cryptobyte"}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/216680"},{"type":"FIX","url":"https://go.googlesource.com/go/+/b13ce14c4a6aa59b7b041ad2b6eed2d23e15b574"},{"type":"WEB","url":"https://go.dev/cl/216677"},{"type":"WEB","url":"https://go.dev/issue/36837"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/Hsw4mHYc470"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2020-7919"},{"type":"WEB","url":"https://github.com/advisories/GHSA-cjjc-xp8v-855w"}]}]
\ No newline at end of file
diff --git a/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/text.json b/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/text.json
index eee052f..e9d55a3 100644
--- a/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/text.json
+++ b/gopls/internal/regtest/misc/testdata/vulndb/golang.org/x/text.json
@@ -1 +1 @@
-[{"id":"GO-2020-0015","published":"2021-04-14T20:04:52Z","modified":"2021-06-07T12:00:00Z","aliases":["CVE-2020-14040"],"details":"An attacker could provide a single byte to a UTF16 decoder instantiated with\nUseBOM or ExpectBOM to trigger an infinite loop if the String function on\nthe Decoder is called, or the Decoder is passed to transform.String.\nIf used to parse user supplied input, this may be used as a denial of service\nvector.\n","affected":[{"package":{"name":"golang.org/x/text/encoding/unicode","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.3"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0015"},"ecosystem_specific":{"symbols":["utf16Decoder.Transform","bomOverride.Transform"]}},{"package":{"name":"golang.org/x/text/transform","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.3"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0015"},"ecosystem_specific":{"symbols":["Transform"]}}],"references":[{"type":"FIX","url":"https://go-review.googlesource.com/c/text/+/238238"},{"type":"FIX","url":"https://go.googlesource.com/text/+/23ae387dee1f90d29a23c0e87ee0b46038fbed0e"},{"type":"WEB","url":"https://go.dev/issue/39491"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0"}]},{"id":"GO-2021-0113","published":"2021-10-06T17:51:21Z","modified":"2021-10-06T17:51:21Z","aliases":["CVE-2021-38561"],"details":"Due to improper index calculation, an incorrectly formatted language tag can cause Parse\nto panic via an out of bounds read. If Parse is used to process untrusted user inputs,\nthis may be used as a vector for a denial of service attack.\n","affected":[{"package":{"name":"golang.org/x/text/language","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.7"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0113"},"ecosystem_specific":{"symbols":["Parse","MatchStrings","MustParse","ParseAcceptLanguage"]}}],"references":[{"type":"FIX","url":"https://go-review.googlesource.com/c/text/+/340830"},{"type":"FIX","url":"https://go.googlesource.com/text/+/383b2e75a7a4198c42f8f87833eefb772868a56f"}]}]
\ No newline at end of file
+[{"id":"GO-2020-0015","published":"2021-04-14T20:04:52Z","modified":"2021-06-07T12:00:00Z","aliases":["CVE-2020-14040","GHSA-5rcv-m4m3-hfh7"],"details":"An attacker could provide a single byte to a UTF16 decoder instantiated with\nUseBOM or ExpectBOM to trigger an infinite loop if the String function on\nthe Decoder is called, or the Decoder is passed to transform.String.\nIf used to parse user supplied input, this may be used as a denial of service\nvector.\n","affected":[{"package":{"name":"golang.org/x/text","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.3"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2020-0015"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/text/encoding/unicode","symbols":["bomOverride.Transform","utf16Decoder.Transform"]},{"path":"golang.org/x/text/transform","symbols":["Transform"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/238238"},{"type":"FIX","url":"https://go.googlesource.com/text/+/23ae387dee1f90d29a23c0e87ee0b46038fbed0e"},{"type":"WEB","url":"https://go.dev/issue/39491"},{"type":"WEB","url":"https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2020-14040"},{"type":"WEB","url":"https://github.com/advisories/GHSA-5rcv-m4m3-hfh7"}]},{"id":"GO-2021-0113","published":"2021-10-06T17:51:21Z","modified":"2021-10-06T17:51:21Z","aliases":["CVE-2021-38561"],"details":"Due to improper index calculation, an incorrectly formatted language tag can cause Parse\nto panic via an out of bounds read. If Parse is used to process untrusted user inputs,\nthis may be used as a vector for a denial of service attack.\n","affected":[{"package":{"name":"golang.org/x/text","ecosystem":"Go"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.7"}]}],"database_specific":{"url":"https://pkg.go.dev/vuln/GO-2021-0113"},"ecosystem_specific":{"imports":[{"path":"golang.org/x/text/language","symbols":["MatchStrings","MustParse","Parse","ParseAcceptLanguage"]}]}}],"references":[{"type":"FIX","url":"https://go.dev/cl/340830"},{"type":"FIX","url":"https://go.googlesource.com/text/+/383b2e75a7a4198c42f8f87833eefb772868a56f"},{"type":"WEB","url":"https://nvd.nist.gov/vuln/detail/CVE-2021-38561"}]}]
\ No newline at end of file
diff --git a/gopls/internal/regtest/misc/testdata/vulndb/stdlib.json b/gopls/internal/regtest/misc/testdata/vulndb/stdlib.json
index 7cbfafc..756727b 100644
--- a/gopls/internal/regtest/misc/testdata/vulndb/stdlib.json
+++ b/gopls/internal/regtest/misc/testdata/vulndb/stdlib.json
@@ -1 +1 @@
-[{"id":"GO-0000-001","affected":[{"package":{"name":"archive/zip"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.18.0"}]}],"ecosystem_specific":{"symbols":["OpenReader"]}}]}]
+[{"id":"STD","affected":[{"package":{"name":"stdlib"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.18.0"}]}],"ecosystem_specific":{"imports":[{"path":"archive/zip","symbols":["OpenReader"]}]}}]}]
diff --git a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/misc/vuln_test.go
index 91fef3f..41d0375 100644
--- a/gopls/internal/regtest/misc/vuln_test.go
+++ b/gopls/internal/regtest/misc/vuln_test.go
@@ -61,7 +61,7 @@
)
func main() {
- _, err := zip.OpenReader("file.zip") // vulnerability GO-0000-001
+ _, err := zip.OpenReader("file.zip") // vulnerability id: STD
fmt.Println(err)
}
`
@@ -111,7 +111,7 @@
env.Await(
CompletedWork("govulncheck", 1, true),
// TODO(hyangah): once the diagnostics are published, wait for diagnostics.
- ShownMessage("Found GO-0000-001"),
+ ShownMessage("Found STD"),
)
})
}
diff --git a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/command.go
index 60d582c..b9aba15 100644
--- a/gopls/internal/vulncheck/command.go
+++ b/gopls/internal/vulncheck/command.go
@@ -175,7 +175,10 @@
for _, v := range vg {
if css := ci.CallStacks[v]; len(css) > 0 {
vuln.CallStacks = append(vuln.CallStacks, toCallStack(css[0]))
- vuln.CallStackSummaries = append(vuln.CallStackSummaries, gvc.SummarizeCallStack(css[0], ci.TopPackages, v.PkgPath))
+ // TODO(hyangah): https://go-review.googlesource.com/c/vuln/+/425183 added position info
+ // in the summary but we don't need the info. Allow SummarizeCallStack to skip it optionally.
+ sum := trimPosPrefix(gvc.SummarizeCallStack(css[0], ci.TopPackages, v.PkgPath))
+ vuln.CallStackSummaries = append(vuln.CallStackSummaries, sum)
}
}
vulns = append(vulns, vuln)
@@ -196,3 +199,11 @@
}
return vulns, nil
}
+
+func trimPosPrefix(summary string) string {
+ _, after, found := strings.Cut(summary, ": ")
+ if !found {
+ return summary
+ }
+ return after
+}
diff --git a/gopls/internal/vulncheck/command_test.go b/gopls/internal/vulncheck/command_test.go
index 71eaf4a..1ce1fae 100644
--- a/gopls/internal/vulncheck/command_test.go
+++ b/gopls/internal/vulncheck/command_test.go
@@ -14,6 +14,7 @@
"os"
"path/filepath"
"sort"
+ "strings"
"testing"
"github.com/google/go-cmp/cmp"
@@ -42,6 +43,13 @@
for _, v := range result {
got = append(got, toReport(v))
}
+ // drop the workspace root directory path included in the summary.
+ cwd := cfg.Dir
+ for _, g := range got {
+ for i, summary := range g.CallStackSummaries {
+ g.CallStackSummaries[i] = strings.ReplaceAll(summary, cwd, ".")
+ }
+ }
var want = []report{
{
@@ -232,9 +240,13 @@
},
},
Affected: []osv.Affected{{
- Package: osv.Package{Name: "golang.org/amod/avuln"},
- Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Introduced: "1.0.0"}, {Fixed: "1.0.4"}, {Introduced: "1.1.2"}}}},
- EcosystemSpecific: osv.EcosystemSpecific{Symbols: []string{"VulnData.Vuln1", "VulnData.Vuln2"}},
+ Package: osv.Package{Name: "golang.org/amod"},
+ Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Introduced: "1.0.0"}, {Fixed: "1.0.4"}, {Introduced: "1.1.2"}}}},
+ EcosystemSpecific: osv.EcosystemSpecific{
+ Imports: []osv.EcosystemSpecificImport{{
+ Path: "golang.org/amod/avuln",
+ Symbols: []string{"VulnData.Vuln1", "VulnData.Vuln2"}}},
+ },
}},
},
{
@@ -247,9 +259,13 @@
},
},
Affected: []osv.Affected{{
- Package: osv.Package{Name: "golang.org/amod/avuln"},
- Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Introduced: "1.0.0"}, {Fixed: "1.0.4"}, {Introduced: "1.1.2"}}}},
- EcosystemSpecific: osv.EcosystemSpecific{Symbols: []string{"nonExisting"}},
+ Package: osv.Package{Name: "golang.org/amod"},
+ Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Introduced: "1.0.0"}, {Fixed: "1.0.4"}, {Introduced: "1.1.2"}}}},
+ EcosystemSpecific: osv.EcosystemSpecific{
+ Imports: []osv.EcosystemSpecificImport{{
+ Path: "golang.org/amod/avuln",
+ Symbols: []string{"nonExisting"}}},
+ },
}},
},
},
@@ -257,9 +273,13 @@
{
ID: "GO-2022-02",
Affected: []osv.Affected{{
- Package: osv.Package{Name: "golang.org/bmod/bvuln"},
- Ranges: osv.Affects{{Type: osv.TypeSemver}},
- EcosystemSpecific: osv.EcosystemSpecific{Symbols: []string{"Vuln"}},
+ Package: osv.Package{Name: "golang.org/bmod"},
+ Ranges: osv.Affects{{Type: osv.TypeSemver}},
+ EcosystemSpecific: osv.EcosystemSpecific{
+ Imports: []osv.EcosystemSpecificImport{{
+ Path: "golang.org/bmod/bvuln",
+ Symbols: []string{"Vuln"}}},
+ },
}},
},
},
To view, visit change 427542. To unsubscribe, or for help writing mail filters, visit settings.