internal/report: disallow overlapping version ranges
When a vulnerability is fixed in (for example) v1.1.1, v1.2.1, and
v1.3.0, OSV describes the vulnerability as applying to the ranges
[0,1.1.1) and [1.2.0,1.2.1). (1.3.0 is not listed, because it comes
after the fix in 1.2.1.)
Check for overlapping ranges in "vulnreport lint". Fix existing
reports with overlapping ranges.
Fixes golang/go#52855.
Change-Id: Ib285a205f5ce7e02485e9fa4763051f053e85000
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/405575
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/report/lint.go b/internal/report/lint.go
index 0e7d068..de5cbe1 100644
--- a/internal/report/lint.go
+++ b/internal/report/lint.go
@@ -181,6 +181,7 @@
addPkgIssue := func(iss string) {
issues = append(issues, fmt.Sprintf("packages[%v]: %v", i, iss))
}
+ versions := p.Versions
if !stdlib.Contains(p.Module) {
if p.Module == "" {
addPkgIssue("missing module")
@@ -207,10 +208,10 @@
}
}
for _, v := range p.Versions {
- if v.Introduced != "" && !strings.HasPrefix(v.Introduced, "v") {
+ if v.Introduced != "" && !semver.IsValid(v.Introduced) {
addPkgIssue(fmt.Sprintf("invalid semantic version: %q", v.Introduced))
}
- if v.Fixed != "" && !strings.HasPrefix(v.Fixed, "v") {
+ if v.Fixed != "" && !semver.IsValid(v.Fixed) {
addPkgIssue(fmt.Sprintf("invalid semantic version: %q", v.Fixed))
}
}
@@ -218,13 +219,31 @@
if p.Package == "" {
addPkgIssue("missing package")
}
+ versions = nil // replace with actual semver versions
for _, v := range p.Versions {
- if v.Introduced != "" && !strings.HasPrefix(v.Introduced, "go") {
+ introduced := "v" + strings.TrimPrefix(v.Introduced, "go")
+ fixed := "v" + strings.TrimPrefix(v.Fixed, "go")
+ if v.Introduced != "" && (!strings.HasPrefix(v.Introduced, "go") || !semver.IsValid(introduced)) {
addPkgIssue(fmt.Sprintf("invalid Go version: %q", v.Introduced))
}
- if v.Fixed != "" && !strings.HasPrefix(v.Fixed, "go") {
+ if v.Fixed != "" && (!strings.HasPrefix(v.Fixed, "go") || !semver.IsValid(fixed)) {
addPkgIssue(fmt.Sprintf("invalid Go version: %q", v.Fixed))
}
+ versions = append(versions, VersionRange{
+ Introduced: introduced,
+ Fixed: fixed,
+ })
+ }
+ }
+ for i, v1 := range versions {
+ if v1.Fixed != "" && semver.Compare(v1.Introduced, v1.Fixed) >= 0 {
+ addPkgIssue(fmt.Sprintf("version %q >= %q", p.Versions[i].Introduced, p.Versions[i].Fixed))
+ continue
+ }
+ for j, v2 := range versions[:i] {
+ if semver.Compare(v1.Fixed, v2.Introduced) > 0 && semver.Compare(v1.Introduced, v2.Fixed) < 0 {
+ addPkgIssue(fmt.Sprintf("version ranges overlap: [%v,%v), [%v,%v)", p.Versions[i].Introduced, p.Versions[i].Fixed, p.Versions[j].Introduced, p.Versions[j].Fixed))
+ }
}
}
}
diff --git a/internal/report/lint_test.go b/internal/report/lint_test.go
new file mode 100644
index 0000000..8f045c2
--- /dev/null
+++ b/internal/report/lint_test.go
@@ -0,0 +1,71 @@
+// 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 report
+
+import (
+ "bytes"
+ "strings"
+ "testing"
+)
+
+func TestLint(t *testing.T) {
+ for _, test := range []struct {
+ report Report
+ want []string
+ }{{
+ report: Report{
+ Packages: []Package{{
+ Module: "std",
+ Package: "time",
+ Versions: []VersionRange{{
+ Fixed: "go1.2.1",
+ }, {
+ Fixed: "go1.3.2",
+ }},
+ }},
+ },
+ want: []string{"version ranges overlap"},
+ }, {
+ report: Report{
+ Packages: []Package{{
+ Module: "std",
+ Package: "time",
+ Versions: []VersionRange{{
+ Introduced: "go1.3",
+ Fixed: "go1.2.1",
+ }},
+ }},
+ },
+ want: []string{`version "go1.3" >= "go1.2.1"`},
+ }} {
+ got := test.report.Lint()
+ var missing []string
+ for _, w := range test.want {
+ found := false
+ for _, g := range got {
+ if strings.Contains(g, w) {
+ found = true
+ continue
+ }
+ }
+ if !found {
+ missing = append(missing, w)
+ }
+ }
+ if len(missing) > 0 {
+ var buf bytes.Buffer
+ if err := test.report.encode(&buf); err != nil {
+ t.Error(err)
+ }
+ t.Errorf("missing expected lint warnings in report:\n%v", buf.String())
+ for _, g := range got {
+ t.Errorf(" got: %v", g)
+ }
+ for _, w := range missing {
+ t.Errorf(" want: %v", w)
+ }
+ }
+ }
+}
diff --git a/reports/GO-2021-0068.yaml b/reports/GO-2021-0068.yaml
index 5213275..e0632c7 100644
--- a/reports/GO-2021-0068.yaml
+++ b/reports/GO-2021-0068.yaml
@@ -4,7 +4,8 @@
package: cmd/go
versions:
- fixed: go1.14.14
- - fixed: go1.15.7
+ - introduced: go1.15.0
+ fixed: go1.15.7
description: |
The go command may execute arbitrary code at build time when using cgo on Windows.
This can be triggered by running go get on a malicious module, or any other time
diff --git a/reports/GO-2021-0140.yaml b/reports/GO-2021-0140.yaml
index 77bbfe2..0c31df1 100644
--- a/reports/GO-2021-0140.yaml
+++ b/reports/GO-2021-0140.yaml
@@ -5,7 +5,8 @@
- Certificate.Verify
versions:
- fixed: go1.13.13
- - fixed: go1.14.5
+ - introduced: go1.14.0
+ fixed: go1.14.5
description: |
X509 Certificate verification does not validate KeyUsages EKU
requirements on Windows if VerifyOptions.Roots is nil.
diff --git a/reports/GO-2021-0141.yaml b/reports/GO-2021-0141.yaml
index b238aaa..b4829bd 100644
--- a/reports/GO-2021-0141.yaml
+++ b/reports/GO-2021-0141.yaml
@@ -5,7 +5,8 @@
- expectContinueReader.Read
versions:
- fixed: go1.13.13
- - fixed: go1.14.5
+ - introduced: go1.14.0
+ fixed: go1.14.5
description: |
A Go HTTP server which reads from the request body while
simultaneously writing a response can panic when clients
diff --git a/reports/GO-2021-0143.yaml b/reports/GO-2021-0143.yaml
index a664c95..12875ac 100644
--- a/reports/GO-2021-0143.yaml
+++ b/reports/GO-2021-0143.yaml
@@ -5,16 +5,16 @@
- response.Write
versions:
- fixed: go1.14.8
- - fixed: go1.15.1
- - fixed: go1.16.0
+ - introduced: go1.15.0
+ fixed: go1.15.1
- module: std
package: net/http/fcgi
symbols:
- response.Write
versions:
- fixed: go1.14.8
- - fixed: go1.15.1
- - fixed: go1.16.0
+ - introduced: go1.15.0
+ fixed: go1.15.1
description: |
When a Handler does not explicitly set the Content-Type header,
the net/http/cgi and net/http/fcgi packages default to "text/html",
diff --git a/reports/GO-2021-0163.yaml b/reports/GO-2021-0163.yaml
index a6b9cef..cbbf883 100644
--- a/reports/GO-2021-0163.yaml
+++ b/reports/GO-2021-0163.yaml
@@ -5,7 +5,8 @@
- LoadLibrary
versions:
- fixed: go1.5.4
- - fixed: go1.6.1
+ - introduced: go1.6.0
+ fixed: go1.6.1
description: |
Untrusted search path vulnerability on Windows related to LoadLibrary allows
local users to gain privileges via a malicious DLL in the current working
diff --git a/reports/GO-2021-0172.yaml b/reports/GO-2021-0172.yaml
index d130765..f2538ba 100644
--- a/reports/GO-2021-0172.yaml
+++ b/reports/GO-2021-0172.yaml
@@ -5,8 +5,8 @@
- Reader.readForm
versions:
- fixed: go1.6.4
- - fixed: go1.7.4
- - fixed: go1.8.0
+ - introduced: go1.7.0
+ fixed: go1.7.4
description: |
When parsing large multipart/form-data, an attacker can
cause a HTTP server to open a large number of file
diff --git a/reports/GO-2021-0178.yaml b/reports/GO-2021-0178.yaml
index 40bd88e..b373d72 100644
--- a/reports/GO-2021-0178.yaml
+++ b/reports/GO-2021-0178.yaml
@@ -6,7 +6,7 @@
versions:
- introduced: go1.1
fixed: go1.8.4
- - introduced: go1.1
+ - introduced: go1.9.0
fixed: go1.9.1
description: |
SMTP clients using net/smtp can use the PLAIN authentication scheme on
diff --git a/reports/GO-2021-0223.yaml b/reports/GO-2021-0223.yaml
index e4d842d..903ee5d 100644
--- a/reports/GO-2021-0223.yaml
+++ b/reports/GO-2021-0223.yaml
@@ -5,8 +5,8 @@
- Certificate.systemVerify
versions:
- fixed: go1.13.13
- - fixed: go1.14.5
- - fixed: go1.15.0
+ - introduced: go1.14.0
+ fixed: go1.14.5
description: |
On Windows, if VerifyOptions.Roots is nil, Certificate.Verify
does not check the EKU requirements specified in VerifyOptions.KeyUsages.
diff --git a/reports/GO-2021-0224.yaml b/reports/GO-2021-0224.yaml
index 0774836..8e5bd21 100644
--- a/reports/GO-2021-0224.yaml
+++ b/reports/GO-2021-0224.yaml
@@ -5,8 +5,8 @@
- expectContinueReader.Read
versions:
- fixed: go1.13.13
- - fixed: go1.14.5
- - fixed: go1.15.0
+ - introduced: go1.14.0
+ fixed: go1.14.5
description: |
HTTP servers where the Handler concurrently reads the request
body and writes a response can encounter a data race and crash.
diff --git a/reports/GO-2021-0225.yaml b/reports/GO-2021-0225.yaml
index b80a2e9..e52414b 100644
--- a/reports/GO-2021-0225.yaml
+++ b/reports/GO-2021-0225.yaml
@@ -5,7 +5,8 @@
- ReadUvarint
versions:
- fixed: go1.13.15
- - fixed: go1.14.7
+ - introduced: go1.14.0
+ fixed: go1.14.7
description: |
Certain invalid inputs to ReadUvarint or ReadVarint could cause those
functions to read an unlimited number of bytes from the ByteReader argument
diff --git a/reports/GO-2021-0226.yaml b/reports/GO-2021-0226.yaml
index 9def5cf..dd0f4d7 100644
--- a/reports/GO-2021-0226.yaml
+++ b/reports/GO-2021-0226.yaml
@@ -7,7 +7,8 @@
- response.writeCGIHeader
versions:
- fixed: go1.14.8
- - fixed: go1.15.1
+ - introduced: go1.15.0
+ fixed: go1.15.1
- module: std
package: net/http/fcgi
symbols:
@@ -16,7 +17,8 @@
- response.writeCGIHeader
versions:
- fixed: go1.14.8
- - fixed: go1.15.1
+ - introduced: go1.15.0
+ fixed: go1.15.1
description: |
When a Handler does not explicitly set the Content-Type header, the the
package would default to “text/html”, which could cause a Cross-Site Scripting
diff --git a/reports/GO-2021-0234.yaml b/reports/GO-2021-0234.yaml
index ad246d6..63702f8 100644
--- a/reports/GO-2021-0234.yaml
+++ b/reports/GO-2021-0234.yaml
@@ -5,8 +5,8 @@
- Decoder.Token
versions:
- fixed: go1.15.9
- - fixed: go1.16.1
- - fixed: go1.17.0
+ - introduced: go1.16.0
+ fixed: go1.16.1
description: |
The Decode, DecodeElement, and Skip methods of an xml.Decoder
provided by xml.NewTokenDecoder may enter an infinite loop when
diff --git a/reports/GO-2021-0235.yaml b/reports/GO-2021-0235.yaml
index 5046fc5..6795732 100644
--- a/reports/GO-2021-0235.yaml
+++ b/reports/GO-2021-0235.yaml
@@ -5,8 +5,8 @@
- p224Contract
versions:
- fixed: go1.14.14
- - fixed: go1.15.7
- - fixed: go1.16.0
+ - introduced: go1.15.0
+ fixed: go1.15.7
description: |
The P224() Curve implementation can in rare circumstances generate
incorrect outputs, including returning invalid points from
diff --git a/reports/GO-2021-0239.yaml b/reports/GO-2021-0239.yaml
index 74c98dc..320a42c 100644
--- a/reports/GO-2021-0239.yaml
+++ b/reports/GO-2021-0239.yaml
@@ -9,8 +9,8 @@
- Resolver.LookupSRV
versions:
- fixed: go1.15.13
- - fixed: go1.16.5
- - fixed: go1.17
+ - introduced: go1.16.0
+ fixed: go1.16.5
description: |
The LookupCNAME, LookupSRV, LookupMX, LookupNS, and LookupAddr
functions and their respective methods on the Resolver type may
diff --git a/reports/GO-2021-0240.yaml b/reports/GO-2021-0240.yaml
index 2b066b3..064868b 100644
--- a/reports/GO-2021-0240.yaml
+++ b/reports/GO-2021-0240.yaml
@@ -5,8 +5,8 @@
- Reader.init
versions:
- fixed: go1.15.13
- - fixed: go1.16.5
- - fixed: go1.17.0
+ - introduced: go1.16.0
+ fixed: go1.16.5
description: |
NewReader and OpenReader can cause a panic or an unrecoverable
fatal error when reading an archive that claims to contain a large
diff --git a/reports/GO-2021-0241.yaml b/reports/GO-2021-0241.yaml
index 79353a6..77cd891 100644
--- a/reports/GO-2021-0241.yaml
+++ b/reports/GO-2021-0241.yaml
@@ -5,8 +5,8 @@
- ReverseProxy.ServeHTTP
versions:
- fixed: go1.15.13
- - fixed: go1.16.5
- - fixed: go1.17.0
+ - introduced: go1.16.0
+ fixed: go1.16.5
description: |
ReverseProxy can be made to forward certain hop-by-hop headers,
including Connection. If the target of the ReverseProxy is
diff --git a/reports/GO-2021-0242.yaml b/reports/GO-2021-0242.yaml
index 0146e35..87209c7 100644
--- a/reports/GO-2021-0242.yaml
+++ b/reports/GO-2021-0242.yaml
@@ -5,8 +5,8 @@
- Rat.SetString
versions:
- fixed: go1.15.13
- - fixed: go1.16.5
- - fixed: go1.17.0
+ - introduced: go1.16.0
+ fixed: go1.16.5
description: |
Rat.SetString and Rat.UnmarshalText may cause a panic or an
unrecoverable fatal error if passed inputs with very large
diff --git a/reports/GO-2021-0243.yaml b/reports/GO-2021-0243.yaml
index 76f30db..066187a 100644
--- a/reports/GO-2021-0243.yaml
+++ b/reports/GO-2021-0243.yaml
@@ -5,8 +5,8 @@
- rsaKeyAgreement.generateClientKeyExchange
versions:
- fixed: go1.15.14
- - fixed: go1.16.6
- - fixed: go1.17.0
+ - introduced: go1.16.0
+ fixed: go1.16.6
description: |
crypto/tls clients can panic when provided a certificate of the
wrong type for the negotiated parameters. net/http clients
diff --git a/reports/GO-2021-0245.yaml b/reports/GO-2021-0245.yaml
index bc0076b..16af7fa 100644
--- a/reports/GO-2021-0245.yaml
+++ b/reports/GO-2021-0245.yaml
@@ -5,8 +5,8 @@
- ReverseProxy.ServeHTTP
versions:
- fixed: go1.15.15
- - fixed: go1.16.7
- - fixed: go1.17.0
+ - introduced: go1.16.0
+ fixed: go1.16.7
description: |
ReverseProxy can panic after encountering a problem copying
a proxied response body.
diff --git a/reports/GO-2021-0263.yaml b/reports/GO-2021-0263.yaml
index 81fd9a3..68458db 100644
--- a/reports/GO-2021-0263.yaml
+++ b/reports/GO-2021-0263.yaml
@@ -4,8 +4,9 @@
symbols:
- NewFile
versions:
- - fixed: go1.17.3
- fixed: go1.16.10
+ - introduced: go1.17.0
+ fixed: go1.17.3
description: |
Calling File.ImportedSymbols on a loaded file which contains an invalid
dynamic symbol table command can cause a panic, in particular if the encoded
diff --git a/reports/GO-2021-0264.yaml b/reports/GO-2021-0264.yaml
index 73fd19b..f24a159 100644
--- a/reports/GO-2021-0264.yaml
+++ b/reports/GO-2021-0264.yaml
@@ -6,7 +6,8 @@
- Reader.Open
versions:
- fixed: go1.16.10
- - fixed: go1.17.3
+ - introduced: go1.17.0
+ fixed: go1.17.3
description: |
Previously, opening a zip with (*Reader).Open could result in a panic if the
zip contained a file whose name was exclusively made up of slash characters or