!122 Synchronize the master branch and openEuler-22.03
From: @hcnbxx Reviewed-by: @zhangsong234, @jing-rui Signed-off-by: @jing-rui
This commit is contained in:
commit
19509c9e51
@ -0,0 +1,60 @@
|
|||||||
|
From ad33fdc8f4bce612842d922ca701c3062fe4d4c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Filippo Valsorda <filippo@golang.org>
|
||||||
|
Date: Thu, 31 Mar 2022 12:31:58 -0400
|
||||||
|
Subject: [Backport 1/2] [release-branch.go1.17] crypto/elliptic: tolerate
|
||||||
|
zero-padded scalars in generic P-256
|
||||||
|
|
||||||
|
Updates #52075
|
||||||
|
Fixes #52076
|
||||||
|
Fixes CVE-2022-28327
|
||||||
|
|
||||||
|
Change-Id: I595a7514c9a0aa1b9c76aedfc2307e1124271f27
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/397136
|
||||||
|
Trust: Filippo Valsorda <filippo@golang.org>
|
||||||
|
Reviewed-by: Julie Qiu <julie@golang.org>
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://go-review.googlesource.com/c/go/+/399816,https://go-review.googlesource.com/c/go/+/397136
|
||||||
|
---
|
||||||
|
src/crypto/elliptic/p256.go | 2 +-
|
||||||
|
src/crypto/elliptic/p256_test.go | 14 ++++++++++++++
|
||||||
|
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/crypto/elliptic/p256.go b/src/crypto/elliptic/p256.go
|
||||||
|
index b2b12c8f13..da5283735c 100644
|
||||||
|
--- a/src/crypto/elliptic/p256.go
|
||||||
|
+++ b/src/crypto/elliptic/p256.go
|
||||||
|
@@ -52,7 +52,7 @@ func p256GetScalar(out *[32]byte, in []byte) {
|
||||||
|
n := new(big.Int).SetBytes(in)
|
||||||
|
var scalarBytes []byte
|
||||||
|
|
||||||
|
- if n.Cmp(p256Params.N) >= 0 {
|
||||||
|
+ if n.Cmp(p256Params.N) >= 0 || len(in) > len(out) {
|
||||||
|
n.Mod(n, p256Params.N)
|
||||||
|
scalarBytes = n.Bytes()
|
||||||
|
} else {
|
||||||
|
diff --git a/src/crypto/elliptic/p256_test.go b/src/crypto/elliptic/p256_test.go
|
||||||
|
index 1435f5e1a5..694186df81 100644
|
||||||
|
--- a/src/crypto/elliptic/p256_test.go
|
||||||
|
+++ b/src/crypto/elliptic/p256_test.go
|
||||||
|
@@ -153,3 +153,17 @@ func TestP256CombinedMult(t *testing.T) {
|
||||||
|
t.Errorf("1×G + (-1)×G = (%d, %d), should be ∞", x, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestIssue52075(t *testing.T) {
|
||||||
|
+ Gx, Gy := P256().Params().Gx, P256().Params().Gy
|
||||||
|
+ scalar := make([]byte, 33)
|
||||||
|
+ scalar[32] = 1
|
||||||
|
+ x, y := P256().ScalarBaseMult(scalar)
|
||||||
|
+ if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
|
||||||
|
+ t.Errorf("unexpected output (%v,%v)", x, y)
|
||||||
|
+ }
|
||||||
|
+ x, y = P256().ScalarMult(Gx, Gy, scalar)
|
||||||
|
+ if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
|
||||||
|
+ t.Errorf("unexpected output (%v,%v)", x, y)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.30.0
|
||||||
|
|
||||||
291
0002-release-branch.go1.17-encoding-pem-fix-stack-overflo.patch
Normal file
291
0002-release-branch.go1.17-encoding-pem-fix-stack-overflo.patch
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
From baaaf3ce29bf98efc00c2f06c531f2b0186b027b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julie Qiu <julie@golang.org>
|
||||||
|
Date: Tue, 1 Mar 2022 10:19:38 -0600
|
||||||
|
Subject: [Backport 2/2] [release-branch.go1.17] encoding/pem: fix stack
|
||||||
|
overflow in Decode
|
||||||
|
|
||||||
|
Previously, Decode called decodeError, a recursive function that was
|
||||||
|
prone to stack overflows when given a large PEM file containing errors.
|
||||||
|
|
||||||
|
Credit to Juho Nurminen of Mattermost who reported the error.
|
||||||
|
|
||||||
|
Fixes CVE-2022-24675
|
||||||
|
Updates #51853
|
||||||
|
Fixes #52036
|
||||||
|
|
||||||
|
Change-Id: Iffe768be53c8ddc0036fea0671d290f8f797692c
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1391157
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
Reviewed-by: Filippo Valsorda <valsorda@google.com>
|
||||||
|
(cherry picked from commit 794ea5e828010e8b68493b2fc6d2963263195a02)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/399816
|
||||||
|
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
|
||||||
|
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||||
|
Reviewed-by: Cherry Mui <cherryyz@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/399816
|
||||||
|
---
|
||||||
|
src/encoding/pem/pem.go | 174 +++++++++++++++--------------------
|
||||||
|
src/encoding/pem/pem_test.go | 28 +++++-
|
||||||
|
2 files changed, 101 insertions(+), 101 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/encoding/pem/pem.go b/src/encoding/pem/pem.go
|
||||||
|
index a7272da5ad..1bee1c12d2 100644
|
||||||
|
--- a/src/encoding/pem/pem.go
|
||||||
|
+++ b/src/encoding/pem/pem.go
|
||||||
|
@@ -87,123 +87,97 @@ func Decode(data []byte) (p *Block, rest []byte) {
|
||||||
|
// pemStart begins with a newline. However, at the very beginning of
|
||||||
|
// the byte array, we'll accept the start string without it.
|
||||||
|
rest = data
|
||||||
|
- if bytes.HasPrefix(data, pemStart[1:]) {
|
||||||
|
- rest = rest[len(pemStart)-1 : len(data)]
|
||||||
|
- } else if i := bytes.Index(data, pemStart); i >= 0 {
|
||||||
|
- rest = rest[i+len(pemStart) : len(data)]
|
||||||
|
- } else {
|
||||||
|
- return nil, data
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- typeLine, rest := getLine(rest)
|
||||||
|
- if !bytes.HasSuffix(typeLine, pemEndOfLine) {
|
||||||
|
- return decodeError(data, rest)
|
||||||
|
- }
|
||||||
|
- typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
|
||||||
|
-
|
||||||
|
- p = &Block{
|
||||||
|
- Headers: make(map[string]string),
|
||||||
|
- Type: string(typeLine),
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
for {
|
||||||
|
- // This loop terminates because getLine's second result is
|
||||||
|
- // always smaller than its argument.
|
||||||
|
- if len(rest) == 0 {
|
||||||
|
+ if bytes.HasPrefix(rest, pemStart[1:]) {
|
||||||
|
+ rest = rest[len(pemStart)-1:]
|
||||||
|
+ } else if i := bytes.Index(rest, pemStart); i >= 0 {
|
||||||
|
+ rest = rest[i+len(pemStart) : len(rest)]
|
||||||
|
+ } else {
|
||||||
|
return nil, data
|
||||||
|
}
|
||||||
|
- line, next := getLine(rest)
|
||||||
|
|
||||||
|
- i := bytes.IndexByte(line, ':')
|
||||||
|
- if i == -1 {
|
||||||
|
- break
|
||||||
|
+ var typeLine []byte
|
||||||
|
+ typeLine, rest = getLine(rest)
|
||||||
|
+ if !bytes.HasSuffix(typeLine, pemEndOfLine) {
|
||||||
|
+ continue
|
||||||
|
}
|
||||||
|
+ typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
|
||||||
|
|
||||||
|
- // TODO(agl): need to cope with values that spread across lines.
|
||||||
|
- key, val := line[:i], line[i+1:]
|
||||||
|
- key = bytes.TrimSpace(key)
|
||||||
|
- val = bytes.TrimSpace(val)
|
||||||
|
- p.Headers[string(key)] = string(val)
|
||||||
|
- rest = next
|
||||||
|
- }
|
||||||
|
+ p = &Block{
|
||||||
|
+ Headers: make(map[string]string),
|
||||||
|
+ Type: string(typeLine),
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- var endIndex, endTrailerIndex int
|
||||||
|
+ for {
|
||||||
|
+ // This loop terminates because getLine's second result is
|
||||||
|
+ // always smaller than its argument.
|
||||||
|
+ if len(rest) == 0 {
|
||||||
|
+ return nil, data
|
||||||
|
+ }
|
||||||
|
+ line, next := getLine(rest)
|
||||||
|
|
||||||
|
- // If there were no headers, the END line might occur
|
||||||
|
- // immediately, without a leading newline.
|
||||||
|
- if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
|
||||||
|
- endIndex = 0
|
||||||
|
- endTrailerIndex = len(pemEnd) - 1
|
||||||
|
- } else {
|
||||||
|
- endIndex = bytes.Index(rest, pemEnd)
|
||||||
|
- endTrailerIndex = endIndex + len(pemEnd)
|
||||||
|
- }
|
||||||
|
+ i := bytes.IndexByte(line, ':')
|
||||||
|
+ if i == -1 {
|
||||||
|
+ break
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if endIndex < 0 {
|
||||||
|
- return decodeError(data, rest)
|
||||||
|
- }
|
||||||
|
+ // TODO(agl): need to cope with values that spread across lines.
|
||||||
|
+ key, val := line[:i], line[i+1:]
|
||||||
|
+ key = bytes.TrimSpace(key)
|
||||||
|
+ val = bytes.TrimSpace(val)
|
||||||
|
+ p.Headers[string(key)] = string(val)
|
||||||
|
+ rest = next
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- // After the "-----" of the ending line, there should be the same type
|
||||||
|
- // and then a final five dashes.
|
||||||
|
- endTrailer := rest[endTrailerIndex:]
|
||||||
|
- endTrailerLen := len(typeLine) + len(pemEndOfLine)
|
||||||
|
- if len(endTrailer) < endTrailerLen {
|
||||||
|
- return decodeError(data, rest)
|
||||||
|
- }
|
||||||
|
+ var endIndex, endTrailerIndex int
|
||||||
|
|
||||||
|
- restOfEndLine := endTrailer[endTrailerLen:]
|
||||||
|
- endTrailer = endTrailer[:endTrailerLen]
|
||||||
|
- if !bytes.HasPrefix(endTrailer, typeLine) ||
|
||||||
|
- !bytes.HasSuffix(endTrailer, pemEndOfLine) {
|
||||||
|
- return decodeError(data, rest)
|
||||||
|
- }
|
||||||
|
+ // If there were no headers, the END line might occur
|
||||||
|
+ // immediately, without a leading newline.
|
||||||
|
+ if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
|
||||||
|
+ endIndex = 0
|
||||||
|
+ endTrailerIndex = len(pemEnd) - 1
|
||||||
|
+ } else {
|
||||||
|
+ endIndex = bytes.Index(rest, pemEnd)
|
||||||
|
+ endTrailerIndex = endIndex + len(pemEnd)
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- // The line must end with only whitespace.
|
||||||
|
- if s, _ := getLine(restOfEndLine); len(s) != 0 {
|
||||||
|
- return decodeError(data, rest)
|
||||||
|
- }
|
||||||
|
+ if endIndex < 0 {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- base64Data := removeSpacesAndTabs(rest[:endIndex])
|
||||||
|
- p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
|
||||||
|
- n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
|
||||||
|
- if err != nil {
|
||||||
|
- return decodeError(data, rest)
|
||||||
|
- }
|
||||||
|
- p.Bytes = p.Bytes[:n]
|
||||||
|
+ // After the "-----" of the ending line, there should be the same type
|
||||||
|
+ // and then a final five dashes.
|
||||||
|
+ endTrailer := rest[endTrailerIndex:]
|
||||||
|
+ endTrailerLen := len(typeLine) + len(pemEndOfLine)
|
||||||
|
+ if len(endTrailer) < endTrailerLen {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ restOfEndLine := endTrailer[endTrailerLen:]
|
||||||
|
+ endTrailer = endTrailer[:endTrailerLen]
|
||||||
|
+ if !bytes.HasPrefix(endTrailer, typeLine) ||
|
||||||
|
+ !bytes.HasSuffix(endTrailer, pemEndOfLine) {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- // the -1 is because we might have only matched pemEnd without the
|
||||||
|
- // leading newline if the PEM block was empty.
|
||||||
|
- _, rest = getLine(rest[endIndex+len(pemEnd)-1:])
|
||||||
|
+ // The line must end with only whitespace.
|
||||||
|
+ if s, _ := getLine(restOfEndLine); len(s) != 0 {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return
|
||||||
|
-}
|
||||||
|
+ base64Data := removeSpacesAndTabs(rest[:endIndex])
|
||||||
|
+ p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
|
||||||
|
+ n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
|
||||||
|
+ if err != nil {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ p.Bytes = p.Bytes[:n]
|
||||||
|
|
||||||
|
-func decodeError(data, rest []byte) (*Block, []byte) {
|
||||||
|
- // If we get here then we have rejected a likely looking, but
|
||||||
|
- // ultimately invalid PEM block. We need to start over from a new
|
||||||
|
- // position. We have consumed the preamble line and will have consumed
|
||||||
|
- // any lines which could be header lines. However, a valid preamble
|
||||||
|
- // line is not a valid header line, therefore we cannot have consumed
|
||||||
|
- // the preamble line for the any subsequent block. Thus, we will always
|
||||||
|
- // find any valid block, no matter what bytes precede it.
|
||||||
|
- //
|
||||||
|
- // For example, if the input is
|
||||||
|
- //
|
||||||
|
- // -----BEGIN MALFORMED BLOCK-----
|
||||||
|
- // junk that may look like header lines
|
||||||
|
- // or data lines, but no END line
|
||||||
|
- //
|
||||||
|
- // -----BEGIN ACTUAL BLOCK-----
|
||||||
|
- // realdata
|
||||||
|
- // -----END ACTUAL BLOCK-----
|
||||||
|
- //
|
||||||
|
- // we've failed to parse using the first BEGIN line
|
||||||
|
- // and now will try again, using the second BEGIN line.
|
||||||
|
- p, rest := Decode(rest)
|
||||||
|
- if p == nil {
|
||||||
|
- rest = data
|
||||||
|
+ // the -1 is because we might have only matched pemEnd without the
|
||||||
|
+ // leading newline if the PEM block was empty.
|
||||||
|
+ _, rest = getLine(rest[endIndex+len(pemEnd)-1:])
|
||||||
|
+ return p, rest
|
||||||
|
}
|
||||||
|
- return p, rest
|
||||||
|
}
|
||||||
|
|
||||||
|
const pemLineLength = 64
|
||||||
|
diff --git a/src/encoding/pem/pem_test.go b/src/encoding/pem/pem_test.go
|
||||||
|
index b2b6b15e73..c94b5ca53b 100644
|
||||||
|
--- a/src/encoding/pem/pem_test.go
|
||||||
|
+++ b/src/encoding/pem/pem_test.go
|
||||||
|
@@ -107,6 +107,12 @@ const pemMissingEndingSpace = `
|
||||||
|
dGVzdA==
|
||||||
|
-----ENDBAR-----`
|
||||||
|
|
||||||
|
+const pemMissingEndLine = `
|
||||||
|
+-----BEGIN FOO-----
|
||||||
|
+Header: 1`
|
||||||
|
+
|
||||||
|
+var pemRepeatingBegin = strings.Repeat("-----BEGIN \n", 10)
|
||||||
|
+
|
||||||
|
var badPEMTests = []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
@@ -131,14 +137,34 @@ var badPEMTests = []struct {
|
||||||
|
"missing ending space",
|
||||||
|
pemMissingEndingSpace,
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ "repeating begin",
|
||||||
|
+ pemRepeatingBegin,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "missing end line",
|
||||||
|
+ pemMissingEndLine,
|
||||||
|
+ },
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBadDecode(t *testing.T) {
|
||||||
|
for _, test := range badPEMTests {
|
||||||
|
- result, _ := Decode([]byte(test.input))
|
||||||
|
+ result, rest := Decode([]byte(test.input))
|
||||||
|
if result != nil {
|
||||||
|
t.Errorf("unexpected success while parsing %q", test.name)
|
||||||
|
}
|
||||||
|
+ if string(rest) != test.input {
|
||||||
|
+ t.Errorf("unexpected rest: %q; want = %q", rest, test.input)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func TestCVE202224675(t *testing.T) {
|
||||||
|
+ // Prior to CVE-2022-24675, this input would cause a stack overflow.
|
||||||
|
+ input := []byte(strings.Repeat("-----BEGIN \n", 10000000))
|
||||||
|
+ result, rest := Decode(input)
|
||||||
|
+ if result != nil || !reflect.DeepEqual(rest, input) {
|
||||||
|
+ t.Errorf("Encode of %#v decoded as %#v", input, rest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.0
|
||||||
|
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
From e7aab832069d06d77e04a585803dfdb04453253a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Russ Cox <rsc@golang.org>
|
||||||
|
Date: Wed, 8 Dec 2021 18:05:11 -0500
|
||||||
|
Subject: [PATCH] [release-branch.go1.17] syscall: fix ForkLock spurious
|
||||||
|
close(0) on pipe failure
|
||||||
|
|
||||||
|
Pipe (and therefore forkLockPipe) does not make any guarantees
|
||||||
|
about the state of p after a failed Pipe(p). Avoid that assumption
|
||||||
|
and the too-clever goto, so that we don't accidentally Close a real fd
|
||||||
|
if the failed pipe leaves p[0] or p[1] set >= 0.
|
||||||
|
|
||||||
|
Updates #50057
|
||||||
|
Fixes CVE-2021-44717
|
||||||
|
|
||||||
|
Change-Id: Iff8e19a6efbba0c73cc8b13ecfae381c87600bb4
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291270
|
||||||
|
Reviewed-by: Ian Lance Taylor <iant@google.com>
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/370534
|
||||||
|
Trust: Filippo Valsorda <filippo@golang.org>
|
||||||
|
Run-TryBot: Filippo Valsorda <filippo@golang.org>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Reviewed-by: Alex Rakoczy <alex@golang.org>
|
||||||
|
---
|
||||||
|
src/syscall/exec_unix.go | 20 ++++++--------------
|
||||||
|
1 file changed, 6 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go
|
||||||
|
index 54b18dccd7..c9c9d1abf3 100644
|
||||||
|
--- a/src/syscall/exec_unix.go
|
||||||
|
+++ b/src/syscall/exec_unix.go
|
||||||
|
@@ -153,9 +153,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
|
||||||
|
sys = &zeroSysProcAttr
|
||||||
|
}
|
||||||
|
|
||||||
|
- p[0] = -1
|
||||||
|
- p[1] = -1
|
||||||
|
-
|
||||||
|
// Convert args to C form.
|
||||||
|
argv0p, err := BytePtrFromString(argv0)
|
||||||
|
if err != nil {
|
||||||
|
@@ -205,14 +202,17 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
|
||||||
|
|
||||||
|
// Allocate child status pipe close on exec.
|
||||||
|
if err = forkExecPipe(p[:]); err != nil {
|
||||||
|
- goto error
|
||||||
|
+ ForkLock.Unlock()
|
||||||
|
+ return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kick off child.
|
||||||
|
pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
|
||||||
|
if err1 != 0 {
|
||||||
|
- err = Errno(err1)
|
||||||
|
- goto error
|
||||||
|
+ Close(p[0])
|
||||||
|
+ Close(p[1])
|
||||||
|
+ ForkLock.Unlock()
|
||||||
|
+ return 0, Errno(err1)
|
||||||
|
}
|
||||||
|
ForkLock.Unlock()
|
||||||
|
|
||||||
|
@@ -244,14 +244,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
|
||||||
|
|
||||||
|
// Read got EOF, so pipe closed on exec, so exec succeeded.
|
||||||
|
return pid, nil
|
||||||
|
-
|
||||||
|
-error:
|
||||||
|
- if p[0] >= 0 {
|
||||||
|
- Close(p[0])
|
||||||
|
- Close(p[1])
|
||||||
|
- }
|
||||||
|
- ForkLock.Unlock()
|
||||||
|
- return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combination of fork and exec, careful to be thread safe.
|
||||||
|
--
|
||||||
|
2.30.0
|
||||||
|
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
From c872b0594f716a2a0799b07d7226a45f02c005f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Cherry Mui <cherryyz@google.com>
|
||||||
|
Date: Wed, 16 Mar 2022 13:07:57 -0400
|
||||||
|
Subject: [PATCH] cmd/link: mark unexported methods for plugins
|
||||||
|
|
||||||
|
When plugin is used, we already mark all exported methods
|
||||||
|
reachable. However, when the plugin and the host program share
|
||||||
|
a common package, an unexported method could also be reachable
|
||||||
|
from both the plugin and the host via interfaces. We need to mark
|
||||||
|
them as well.
|
||||||
|
|
||||||
|
Fixes #51621.
|
||||||
|
|
||||||
|
Change-Id: I1a70d3f96b66b803f2d0ab14d00ed0df276ea500
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/393365
|
||||||
|
Trust: Cherry Mui <cherryyz@google.com>
|
||||||
|
Run-TryBot: Cherry Mui <cherryyz@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Reviewed-by: Than McIntosh <thanm@google.com>
|
||||||
|
---
|
||||||
|
src/cmd/link/internal/ld/deadcode.go | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
|
||||||
|
index e4fa75f..21a9703 100644
|
||||||
|
--- a/src/cmd/link/internal/ld/deadcode.go
|
||||||
|
+++ b/src/cmd/link/internal/ld/deadcode.go
|
||||||
|
@@ -350,7 +350,7 @@ func deadcode(ctxt *Link) {
|
||||||
|
// in the last pass.
|
||||||
|
rem := d.markableMethods[:0]
|
||||||
|
for _, m := range d.markableMethods {
|
||||||
|
- if (d.reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
|
||||||
|
+ if (d.reflectSeen && (m.isExported() || d.dynlink)) || d.ifaceMethod[m.m] {
|
||||||
|
d.markMethod(m)
|
||||||
|
} else {
|
||||||
|
rem = append(rem, m)
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
From 67bff2eb995a098f838fa4b799c0b8261292e6e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Damien Neil <dneil@google.com>
|
||||||
|
Date: Fri, 17 Jun 2022 10:09:45 -0700
|
||||||
|
Subject: [PATCH 01/11] [release-branch.go1.17] net/http: preserve nil values
|
||||||
|
in Header.Clone
|
||||||
|
|
||||||
|
ReverseProxy makes a distinction between nil and zero-length header values.
|
||||||
|
Avoid losing nil-ness when cloning a request.
|
||||||
|
|
||||||
|
Thanks to Christian Mehlmauer for discovering this.
|
||||||
|
|
||||||
|
For #53423
|
||||||
|
For CVE-2022-32148
|
||||||
|
Fixes #53620
|
||||||
|
|
||||||
|
Change-Id: Ice369cdb4712e2d62e25bb881b080847aa4801f5
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/412857
|
||||||
|
Reviewed-by: Ian Lance Taylor <iant@google.com>
|
||||||
|
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
|
||||||
|
(cherry picked from commit b2cc0fecc2ccd80e6d5d16542cc684f97b3a9c8a)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/415221
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
Run-TryBot: Heschi Kreinick <heschi@google.com>
|
||||||
|
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/415221
|
||||||
|
---
|
||||||
|
src/net/http/header.go | 6 ++++++
|
||||||
|
src/net/http/header_test.go | 5 +++++
|
||||||
|
2 files changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/net/http/header.go b/src/net/http/header.go
|
||||||
|
index 4c72dcb2c88..ef4ee7ffa81 100644
|
||||||
|
--- a/src/net/http/header.go
|
||||||
|
+++ b/src/net/http/header.go
|
||||||
|
@@ -101,6 +101,12 @@ func (h Header) Clone() Header {
|
||||||
|
sv := make([]string, nv) // shared backing array for headers' values
|
||||||
|
h2 := make(Header, len(h))
|
||||||
|
for k, vv := range h {
|
||||||
|
+ if vv == nil {
|
||||||
|
+ // Preserve nil values. ReverseProxy distinguishes
|
||||||
|
+ // between nil and zero-length header values.
|
||||||
|
+ h2[k] = nil
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
n := copy(sv, vv)
|
||||||
|
h2[k] = sv[:n:n]
|
||||||
|
sv = sv[n:]
|
||||||
|
diff --git a/src/net/http/header_test.go b/src/net/http/header_test.go
|
||||||
|
index 47893629194..80c003551db 100644
|
||||||
|
--- a/src/net/http/header_test.go
|
||||||
|
+++ b/src/net/http/header_test.go
|
||||||
|
@@ -235,6 +235,11 @@ func TestCloneOrMakeHeader(t *testing.T) {
|
||||||
|
in: Header{"foo": {"bar"}},
|
||||||
|
want: Header{"foo": {"bar"}},
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ name: "nil value",
|
||||||
|
+ in: Header{"foo": nil},
|
||||||
|
+ want: Header{"foo": nil},
|
||||||
|
+ },
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
421
0006-release-branch.go1.17-go-parser-limit-recursion-dept.patch
Normal file
421
0006-release-branch.go1.17-go-parser-limit-recursion-dept.patch
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
From b78e521644334294019da243a5ff57436f70cd72 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <bracewell@google.com>
|
||||||
|
Date: Wed, 15 Jun 2022 10:43:05 -0700
|
||||||
|
Subject: [PATCH 02/11] [release-branch.go1.17] go/parser: limit recursion
|
||||||
|
depth
|
||||||
|
|
||||||
|
Limit nested parsing to 100,000, which prevents stack exhaustion when
|
||||||
|
parsing deeply nested statements, types, and expressions. Also limit
|
||||||
|
the scope depth to 1,000 during object resolution.
|
||||||
|
|
||||||
|
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
||||||
|
|
||||||
|
Fixes #53707
|
||||||
|
Updates #53616
|
||||||
|
Fixes CVE-2022-1962
|
||||||
|
|
||||||
|
Change-Id: I4d7b86c1d75d0bf3c7af1fdea91582aa74272c64
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1491025
|
||||||
|
Reviewed-by: Russ Cox <rsc@google.com>
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
(cherry picked from commit 6a856f08d58e4b6705c0c337d461c540c1235c83)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417070
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417070
|
||||||
|
---
|
||||||
|
src/go/parser/interface.go | 10 ++-
|
||||||
|
src/go/parser/parser.go | 54 ++++++++++-
|
||||||
|
src/go/parser/parser_test.go | 169 +++++++++++++++++++++++++++++++++++
|
||||||
|
src/go/parser/resolver.go | 9 ++
|
||||||
|
4 files changed, 236 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go
|
||||||
|
index 85486d2f4b4..eae429e6ef3 100644
|
||||||
|
--- a/src/go/parser/interface.go
|
||||||
|
+++ b/src/go/parser/interface.go
|
||||||
|
@@ -97,8 +97,11 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode)
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
// resume same panic if it's not a bailout
|
||||||
|
- if _, ok := e.(bailout); !ok {
|
||||||
|
+ bail, ok := e.(bailout)
|
||||||
|
+ if !ok {
|
||||||
|
panic(e)
|
||||||
|
+ } else if bail.msg != "" {
|
||||||
|
+ p.errors.Add(p.file.Position(bail.pos), bail.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -203,8 +206,11 @@ func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode M
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
// resume same panic if it's not a bailout
|
||||||
|
- if _, ok := e.(bailout); !ok {
|
||||||
|
+ bail, ok := e.(bailout)
|
||||||
|
+ if !ok {
|
||||||
|
panic(e)
|
||||||
|
+ } else if bail.msg != "" {
|
||||||
|
+ p.errors.Add(p.file.Position(bail.pos), bail.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.errors.Sort()
|
||||||
|
diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
|
||||||
|
index f10c8650afd..2c42b9f8cc2 100644
|
||||||
|
--- a/src/go/parser/parser.go
|
||||||
|
+++ b/src/go/parser/parser.go
|
||||||
|
@@ -60,6 +60,10 @@ type parser struct {
|
||||||
|
inRhs bool // if set, the parser is parsing a rhs expression
|
||||||
|
|
||||||
|
imports []*ast.ImportSpec // list of imports
|
||||||
|
+
|
||||||
|
+ // nestLev is used to track and limit the recursion depth
|
||||||
|
+ // during parsing.
|
||||||
|
+ nestLev int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
|
||||||
|
@@ -110,6 +114,24 @@ func un(p *parser) {
|
||||||
|
p.printTrace(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
+// maxNestLev is the deepest we're willing to recurse during parsing
|
||||||
|
+const maxNestLev int = 1e5
|
||||||
|
+
|
||||||
|
+func incNestLev(p *parser) *parser {
|
||||||
|
+ p.nestLev++
|
||||||
|
+ if p.nestLev > maxNestLev {
|
||||||
|
+ p.error(p.pos, "exceeded max nesting depth")
|
||||||
|
+ panic(bailout{})
|
||||||
|
+ }
|
||||||
|
+ return p
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// decNestLev is used to track nesting depth during parsing to prevent stack exhaustion.
|
||||||
|
+// It is used along with incNestLev in a similar fashion to how un and trace are used.
|
||||||
|
+func decNestLev(p *parser) {
|
||||||
|
+ p.nestLev--
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Advance to the next token.
|
||||||
|
func (p *parser) next0() {
|
||||||
|
// Because of one-token look-ahead, print the previous token
|
||||||
|
@@ -222,8 +244,12 @@ func (p *parser) next() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-// A bailout panic is raised to indicate early termination.
|
||||||
|
-type bailout struct{}
|
||||||
|
+// A bailout panic is raised to indicate early termination. pos and msg are
|
||||||
|
+// only populated when bailing out of object resolution.
|
||||||
|
+type bailout struct {
|
||||||
|
+ pos token.Pos
|
||||||
|
+ msg string
|
||||||
|
+}
|
||||||
|
|
||||||
|
func (p *parser) error(pos token.Pos, msg string) {
|
||||||
|
if p.trace {
|
||||||
|
@@ -1119,6 +1145,8 @@ func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) tryIdentOrType() ast.Expr {
|
||||||
|
+ defer decNestLev(incNestLev(p))
|
||||||
|
+
|
||||||
|
switch p.tok {
|
||||||
|
case token.IDENT:
|
||||||
|
typ := p.parseTypeName(nil)
|
||||||
|
@@ -1531,7 +1559,13 @@ func (p *parser) parsePrimaryExpr() (x ast.Expr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
x = p.parseOperand()
|
||||||
|
- for {
|
||||||
|
+ // We track the nesting here rather than at the entry for the function,
|
||||||
|
+ // since it can iteratively produce a nested output, and we want to
|
||||||
|
+ // limit how deep a structure we generate.
|
||||||
|
+ var n int
|
||||||
|
+ defer func() { p.nestLev -= n }()
|
||||||
|
+ for n = 1; ; n++ {
|
||||||
|
+ incNestLev(p)
|
||||||
|
switch p.tok {
|
||||||
|
case token.PERIOD:
|
||||||
|
p.next()
|
||||||
|
@@ -1591,6 +1625,8 @@ func (p *parser) parsePrimaryExpr() (x ast.Expr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) parseUnaryExpr() ast.Expr {
|
||||||
|
+ defer decNestLev(incNestLev(p))
|
||||||
|
+
|
||||||
|
if p.trace {
|
||||||
|
defer un(trace(p, "UnaryExpr"))
|
||||||
|
}
|
||||||
|
@@ -1673,7 +1709,13 @@ func (p *parser) parseBinaryExpr(prec1 int) ast.Expr {
|
||||||
|
}
|
||||||
|
|
||||||
|
x := p.parseUnaryExpr()
|
||||||
|
- for {
|
||||||
|
+ // We track the nesting here rather than at the entry for the function,
|
||||||
|
+ // since it can iteratively produce a nested output, and we want to
|
||||||
|
+ // limit how deep a structure we generate.
|
||||||
|
+ var n int
|
||||||
|
+ defer func() { p.nestLev -= n }()
|
||||||
|
+ for n = 1; ; n++ {
|
||||||
|
+ incNestLev(p)
|
||||||
|
op, oprec := p.tokPrec()
|
||||||
|
if oprec < prec1 {
|
||||||
|
return x
|
||||||
|
@@ -1962,6 +2004,8 @@ func (p *parser) parseIfHeader() (init ast.Stmt, cond ast.Expr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) parseIfStmt() *ast.IfStmt {
|
||||||
|
+ defer decNestLev(incNestLev(p))
|
||||||
|
+
|
||||||
|
if p.trace {
|
||||||
|
defer un(trace(p, "IfStmt"))
|
||||||
|
}
|
||||||
|
@@ -2265,6 +2309,8 @@ func (p *parser) parseForStmt() ast.Stmt {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) parseStmt() (s ast.Stmt) {
|
||||||
|
+ defer decNestLev(incNestLev(p))
|
||||||
|
+
|
||||||
|
if p.trace {
|
||||||
|
defer un(trace(p, "Statement"))
|
||||||
|
}
|
||||||
|
diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go
|
||||||
|
index a4f882d3688..1a46c878663 100644
|
||||||
|
--- a/src/go/parser/parser_test.go
|
||||||
|
+++ b/src/go/parser/parser_test.go
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
||||||
|
"go/ast"
|
||||||
|
"go/token"
|
||||||
|
"io/fs"
|
||||||
|
+ "runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
@@ -577,3 +578,171 @@ type x int // comment
|
||||||
|
t.Errorf("got %q, want %q", comment, "// comment")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+var parseDepthTests = []struct {
|
||||||
|
+ name string
|
||||||
|
+ format string
|
||||||
|
+ // multipler is used when a single statement may result in more than one
|
||||||
|
+ // change in the depth level, for instance "1+(..." produces a BinaryExpr
|
||||||
|
+ // followed by a UnaryExpr, which increments the depth twice. The test
|
||||||
|
+ // case comment explains which nodes are triggering the multiple depth
|
||||||
|
+ // changes.
|
||||||
|
+ parseMultiplier int
|
||||||
|
+ // scope is true if we should also test the statement for the resolver scope
|
||||||
|
+ // depth limit.
|
||||||
|
+ scope bool
|
||||||
|
+ // scopeMultiplier does the same as parseMultiplier, but for the scope
|
||||||
|
+ // depths.
|
||||||
|
+ scopeMultiplier int
|
||||||
|
+}{
|
||||||
|
+ // The format expands the part inside « » many times.
|
||||||
|
+ // A second set of brackets nested inside the first stops the repetition,
|
||||||
|
+ // so that for example «(«1»)» expands to (((...((((1))))...))).
|
||||||
|
+ {name: "array", format: "package main; var x «[1]»int"},
|
||||||
|
+ {name: "slice", format: "package main; var x «[]»int"},
|
||||||
|
+ {name: "struct", format: "package main; var x «struct { X «int» }»", scope: true},
|
||||||
|
+ {name: "pointer", format: "package main; var x «*»int"},
|
||||||
|
+ {name: "func", format: "package main; var x «func()»int", scope: true},
|
||||||
|
+ {name: "chan", format: "package main; var x «chan »int"},
|
||||||
|
+ {name: "chan2", format: "package main; var x «<-chan »int"},
|
||||||
|
+ {name: "interface", format: "package main; var x «interface { M() «int» }»", scope: true, scopeMultiplier: 2}, // Scopes: InterfaceType, FuncType
|
||||||
|
+ {name: "map", format: "package main; var x «map[int]»int"},
|
||||||
|
+ {name: "slicelit", format: "package main; var x = «[]any{«»}»", parseMultiplier: 2}, // Parser nodes: UnaryExpr, CompositeLit
|
||||||
|
+ {name: "arraylit", format: "package main; var x = «[1]any{«nil»}»", parseMultiplier: 2}, // Parser nodes: UnaryExpr, CompositeLit
|
||||||
|
+ {name: "structlit", format: "package main; var x = «struct{x any}{«nil»}»", parseMultiplier: 2}, // Parser nodes: UnaryExpr, CompositeLit
|
||||||
|
+ {name: "maplit", format: "package main; var x = «map[int]any{1:«nil»}»", parseMultiplier: 2}, // Parser nodes: CompositeLit, KeyValueExpr
|
||||||
|
+ {name: "dot", format: "package main; var x = «x.»x"},
|
||||||
|
+ {name: "index", format: "package main; var x = x«[1]»"},
|
||||||
|
+ {name: "slice", format: "package main; var x = x«[1:2]»"},
|
||||||
|
+ {name: "slice3", format: "package main; var x = x«[1:2:3]»"},
|
||||||
|
+ {name: "dottype", format: "package main; var x = x«.(any)»"},
|
||||||
|
+ {name: "callseq", format: "package main; var x = x«()»"},
|
||||||
|
+ {name: "methseq", format: "package main; var x = x«.m()»", parseMultiplier: 2}, // Parser nodes: SelectorExpr, CallExpr
|
||||||
|
+ {name: "binary", format: "package main; var x = «1+»1"},
|
||||||
|
+ {name: "binaryparen", format: "package main; var x = «1+(«1»)»", parseMultiplier: 2}, // Parser nodes: BinaryExpr, ParenExpr
|
||||||
|
+ {name: "unary", format: "package main; var x = «^»1"},
|
||||||
|
+ {name: "addr", format: "package main; var x = «& »x"},
|
||||||
|
+ {name: "star", format: "package main; var x = «*»x"},
|
||||||
|
+ {name: "recv", format: "package main; var x = «<-»x"},
|
||||||
|
+ {name: "call", format: "package main; var x = «f(«1»)»", parseMultiplier: 2}, // Parser nodes: Ident, CallExpr
|
||||||
|
+ {name: "conv", format: "package main; var x = «(*T)(«1»)»", parseMultiplier: 2}, // Parser nodes: ParenExpr, CallExpr
|
||||||
|
+ {name: "label", format: "package main; func main() { «Label:» }"},
|
||||||
|
+ {name: "if", format: "package main; func main() { «if true { «» }»}", parseMultiplier: 2, scope: true, scopeMultiplier: 2}, // Parser nodes: IfStmt, BlockStmt. Scopes: IfStmt, BlockStmt
|
||||||
|
+ {name: "ifelse", format: "package main; func main() { «if true {} else » {} }", scope: true},
|
||||||
|
+ {name: "switch", format: "package main; func main() { «switch { default: «» }»}", scope: true, scopeMultiplier: 2}, // Scopes: TypeSwitchStmt, CaseClause
|
||||||
|
+ {name: "typeswitch", format: "package main; func main() { «switch x.(type) { default: «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: TypeSwitchStmt, CaseClause
|
||||||
|
+ {name: "for0", format: "package main; func main() { «for { «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: ForStmt, BlockStmt
|
||||||
|
+ {name: "for1", format: "package main; func main() { «for x { «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: ForStmt, BlockStmt
|
||||||
|
+ {name: "for3", format: "package main; func main() { «for f(); g(); h() { «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: ForStmt, BlockStmt
|
||||||
|
+ {name: "forrange0", format: "package main; func main() { «for range x { «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: RangeStmt, BlockStmt
|
||||||
|
+ {name: "forrange1", format: "package main; func main() { «for x = range z { «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: RangeStmt, BlockStmt
|
||||||
|
+ {name: "forrange2", format: "package main; func main() { «for x, y = range z { «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: RangeStmt, BlockStmt
|
||||||
|
+ {name: "go", format: "package main; func main() { «go func() { «» }()» }", parseMultiplier: 2, scope: true}, // Parser nodes: GoStmt, FuncLit
|
||||||
|
+ {name: "defer", format: "package main; func main() { «defer func() { «» }()» }", parseMultiplier: 2, scope: true}, // Parser nodes: DeferStmt, FuncLit
|
||||||
|
+ {name: "select", format: "package main; func main() { «select { default: «» }» }", scope: true},
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// split splits pre«mid»post into pre, mid, post.
|
||||||
|
+// If the string does not have that form, split returns x, "", "".
|
||||||
|
+func split(x string) (pre, mid, post string) {
|
||||||
|
+ start, end := strings.Index(x, "«"), strings.LastIndex(x, "»")
|
||||||
|
+ if start < 0 || end < 0 {
|
||||||
|
+ return x, "", ""
|
||||||
|
+ }
|
||||||
|
+ return x[:start], x[start+len("«") : end], x[end+len("»"):]
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func TestParseDepthLimit(t *testing.T) {
|
||||||
|
+ if runtime.GOARCH == "wasm" {
|
||||||
|
+ t.Skip("causes call stack exhaustion on js/wasm")
|
||||||
|
+ }
|
||||||
|
+ for _, tt := range parseDepthTests {
|
||||||
|
+ for _, size := range []string{"small", "big"} {
|
||||||
|
+ t.Run(tt.name+"/"+size, func(t *testing.T) {
|
||||||
|
+ n := maxNestLev + 1
|
||||||
|
+ if tt.parseMultiplier > 0 {
|
||||||
|
+ n /= tt.parseMultiplier
|
||||||
|
+ }
|
||||||
|
+ if size == "small" {
|
||||||
|
+ // Decrease the number of statements by 10, in order to check
|
||||||
|
+ // that we do not fail when under the limit. 10 is used to
|
||||||
|
+ // provide some wiggle room for cases where the surrounding
|
||||||
|
+ // scaffolding syntax adds some noise to the depth that changes
|
||||||
|
+ // on a per testcase basis.
|
||||||
|
+ n -= 10
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pre, mid, post := split(tt.format)
|
||||||
|
+ if strings.Contains(mid, "«") {
|
||||||
|
+ left, base, right := split(mid)
|
||||||
|
+ mid = strings.Repeat(left, n) + base + strings.Repeat(right, n)
|
||||||
|
+ } else {
|
||||||
|
+ mid = strings.Repeat(mid, n)
|
||||||
|
+ }
|
||||||
|
+ input := pre + mid + post
|
||||||
|
+
|
||||||
|
+ fset := token.NewFileSet()
|
||||||
|
+ _, err := ParseFile(fset, "", input, ParseComments|SkipObjectResolution)
|
||||||
|
+ if size == "small" {
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Errorf("ParseFile(...): %v (want success)", err)
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ expected := "exceeded max nesting depth"
|
||||||
|
+ if err == nil || !strings.HasSuffix(err.Error(), expected) {
|
||||||
|
+ t.Errorf("ParseFile(...) = _, %v, want %q", err, expected)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ })
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func TestScopeDepthLimit(t *testing.T) {
|
||||||
|
+ if runtime.GOARCH == "wasm" {
|
||||||
|
+ t.Skip("causes call stack exhaustion on js/wasm")
|
||||||
|
+ }
|
||||||
|
+ for _, tt := range parseDepthTests {
|
||||||
|
+ if !tt.scope {
|
||||||
|
+ continue
|
||||||
|
+ }
|
||||||
|
+ for _, size := range []string{"small", "big"} {
|
||||||
|
+ t.Run(tt.name+"/"+size, func(t *testing.T) {
|
||||||
|
+ n := maxScopeDepth + 1
|
||||||
|
+ if tt.scopeMultiplier > 0 {
|
||||||
|
+ n /= tt.scopeMultiplier
|
||||||
|
+ }
|
||||||
|
+ if size == "small" {
|
||||||
|
+ // Decrease the number of statements by 10, in order to check
|
||||||
|
+ // that we do not fail when under the limit. 10 is used to
|
||||||
|
+ // provide some wiggle room for cases where the surrounding
|
||||||
|
+ // scaffolding syntax adds some noise to the depth that changes
|
||||||
|
+ // on a per testcase basis.
|
||||||
|
+ n -= 10
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pre, mid, post := split(tt.format)
|
||||||
|
+ if strings.Contains(mid, "«") {
|
||||||
|
+ left, base, right := split(mid)
|
||||||
|
+ mid = strings.Repeat(left, n) + base + strings.Repeat(right, n)
|
||||||
|
+ } else {
|
||||||
|
+ mid = strings.Repeat(mid, n)
|
||||||
|
+ }
|
||||||
|
+ input := pre + mid + post
|
||||||
|
+
|
||||||
|
+ fset := token.NewFileSet()
|
||||||
|
+ _, err := ParseFile(fset, "", input, DeclarationErrors)
|
||||||
|
+ if size == "small" {
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Errorf("ParseFile(...): %v (want success)", err)
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ expected := "exceeded max scope depth during object resolution"
|
||||||
|
+ if err == nil || !strings.HasSuffix(err.Error(), expected) {
|
||||||
|
+ t.Errorf("ParseFile(...) = _, %v, want %q", err, expected)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ })
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/go/parser/resolver.go b/src/go/parser/resolver.go
|
||||||
|
index cf92c7e4f57..f55bdb7f177 100644
|
||||||
|
--- a/src/go/parser/resolver.go
|
||||||
|
+++ b/src/go/parser/resolver.go
|
||||||
|
@@ -25,6 +25,7 @@ func resolveFile(file *ast.File, handle *token.File, declErr func(token.Pos, str
|
||||||
|
declErr: declErr,
|
||||||
|
topScope: pkgScope,
|
||||||
|
pkgScope: pkgScope,
|
||||||
|
+ depth: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, decl := range file.Decls {
|
||||||
|
@@ -53,6 +54,8 @@ func resolveFile(file *ast.File, handle *token.File, declErr func(token.Pos, str
|
||||||
|
file.Unresolved = r.unresolved[0:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
+const maxScopeDepth int = 1e3
|
||||||
|
+
|
||||||
|
type resolver struct {
|
||||||
|
handle *token.File
|
||||||
|
declErr func(token.Pos, string)
|
||||||
|
@@ -61,6 +64,7 @@ type resolver struct {
|
||||||
|
pkgScope *ast.Scope // pkgScope.Outer == nil
|
||||||
|
topScope *ast.Scope // top-most scope; may be pkgScope
|
||||||
|
unresolved []*ast.Ident // unresolved identifiers
|
||||||
|
+ depth int // scope depth
|
||||||
|
|
||||||
|
// Label scopes
|
||||||
|
// (maintained by open/close LabelScope)
|
||||||
|
@@ -83,6 +87,10 @@ func (r *resolver) sprintf(format string, args ...interface{}) string {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolver) openScope(pos token.Pos) {
|
||||||
|
+ r.depth++
|
||||||
|
+ if r.depth > maxScopeDepth {
|
||||||
|
+ panic(bailout{pos: pos, msg: "exceeded max scope depth during object resolution"})
|
||||||
|
+ }
|
||||||
|
if debugResolve {
|
||||||
|
r.dump("opening scope @%v", pos)
|
||||||
|
}
|
||||||
|
@@ -90,6 +98,7 @@ func (r *resolver) openScope(pos token.Pos) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resolver) closeScope() {
|
||||||
|
+ r.depth--
|
||||||
|
if debugResolve {
|
||||||
|
r.dump("closing scope")
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
From 4ad62aecaf57ca3adc11a04bd2113bdbee6249c3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Damien Neil <dneil@google.com>
|
||||||
|
Date: Wed, 1 Jun 2022 11:17:07 -0700
|
||||||
|
Subject: [PATCH 03/11] [release-branch.go1.17] net/http: don't strip
|
||||||
|
whitespace from Transfer-Encoding headers
|
||||||
|
|
||||||
|
Do not accept "Transfer-Encoding: \rchunked" as a valid TE header
|
||||||
|
setting chunked encoding.
|
||||||
|
|
||||||
|
Thanks to Zeyu Zhang (https://www.zeyu2001.com/) for identifying
|
||||||
|
the issue.
|
||||||
|
|
||||||
|
For #53188
|
||||||
|
For CVE-2022-1705
|
||||||
|
Fixes #53432
|
||||||
|
|
||||||
|
Change-Id: I1a16631425159267f2eca68056b057192a7edf6c
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/409874
|
||||||
|
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||||
|
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
|
||||||
|
(cherry picked from commit e5017a93fcde94f09836200bca55324af037ee5f)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/415217
|
||||||
|
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
|
||||||
|
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
|
||||||
|
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/415217
|
||||||
|
---
|
||||||
|
src/net/http/serve_test.go | 1 +
|
||||||
|
src/net/http/transfer.go | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
|
||||||
|
index 6394da3bb7c..bfac783e3a9 100644
|
||||||
|
--- a/src/net/http/serve_test.go
|
||||||
|
+++ b/src/net/http/serve_test.go
|
||||||
|
@@ -6189,6 +6189,7 @@ func TestUnsupportedTransferEncodingsReturn501(t *testing.T) {
|
||||||
|
"fugazi",
|
||||||
|
"foo-bar",
|
||||||
|
"unknown",
|
||||||
|
+ "\rchunked",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, badTE := range unsupportedTEs {
|
||||||
|
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
|
||||||
|
index 85c2e5a360d..3894007d306 100644
|
||||||
|
--- a/src/net/http/transfer.go
|
||||||
|
+++ b/src/net/http/transfer.go
|
||||||
|
@@ -639,7 +639,7 @@ func (t *transferReader) parseTransferEncoding() error {
|
||||||
|
if len(raw) != 1 {
|
||||||
|
return &unsupportedTEError{fmt.Sprintf("too many transfer encodings: %q", raw)}
|
||||||
|
}
|
||||||
|
- if !ascii.EqualFold(textproto.TrimString(raw[0]), "chunked") {
|
||||||
|
+ if !ascii.EqualFold(raw[0], "chunked") {
|
||||||
|
return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", raw[0])}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
168
0008-release-branch.go1.17-encoding-xml-limit-depth-of-ne.patch
Normal file
168
0008-release-branch.go1.17-encoding-xml-limit-depth-of-ne.patch
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
From 106c859f68c3137cfa05c433a9b90494db386fda Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <roland@golang.org>
|
||||||
|
Date: Tue, 29 Mar 2022 15:52:09 -0700
|
||||||
|
Subject: [PATCH 04/11] [release-branch.go1.17] encoding/xml: limit depth of
|
||||||
|
nesting in unmarshal
|
||||||
|
|
||||||
|
Prevent exhausting the stack limit when unmarshalling extremely deeply
|
||||||
|
nested structures into nested types.
|
||||||
|
|
||||||
|
Fixes #53715
|
||||||
|
Updates #53611
|
||||||
|
Fixes CVE-2022-30633
|
||||||
|
|
||||||
|
Change-Id: Ic6c5d41674c93cfc9a316135a408db9156d39c59
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1421319
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||||
|
(cherry picked from commit ebee00a55e28931b2cad0e76207a73712b000432)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417069
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417069
|
||||||
|
---
|
||||||
|
src/encoding/xml/read.go | 27 +++++++++++++++++++--------
|
||||||
|
src/encoding/xml/read_test.go | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 51 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
|
||||||
|
index ef5df3f7f6a..e0ed8b527ce 100644
|
||||||
|
--- a/src/encoding/xml/read.go
|
||||||
|
+++ b/src/encoding/xml/read.go
|
||||||
|
@@ -148,7 +148,7 @@ func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error {
|
||||||
|
if val.Kind() != reflect.Ptr {
|
||||||
|
return errors.New("non-pointer passed to Unmarshal")
|
||||||
|
}
|
||||||
|
- return d.unmarshal(val.Elem(), start)
|
||||||
|
+ return d.unmarshal(val.Elem(), start, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// An UnmarshalError represents an error in the unmarshaling process.
|
||||||
|
@@ -304,8 +304,15 @@ var (
|
||||||
|
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
|
||||||
|
)
|
||||||
|
|
||||||
|
+const maxUnmarshalDepth = 10000
|
||||||
|
+
|
||||||
|
+var errExeceededMaxUnmarshalDepth = errors.New("exceeded max depth")
|
||||||
|
+
|
||||||
|
// Unmarshal a single XML element into val.
|
||||||
|
-func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
||||||
|
+func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) error {
|
||||||
|
+ if depth >= maxUnmarshalDepth {
|
||||||
|
+ return errExeceededMaxUnmarshalDepth
|
||||||
|
+ }
|
||||||
|
// Find start element if we need it.
|
||||||
|
if start == nil {
|
||||||
|
for {
|
||||||
|
@@ -398,7 +405,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
||||||
|
v.Set(reflect.Append(val, reflect.Zero(v.Type().Elem())))
|
||||||
|
|
||||||
|
// Recur to read element into slice.
|
||||||
|
- if err := d.unmarshal(v.Index(n), start); err != nil {
|
||||||
|
+ if err := d.unmarshal(v.Index(n), start, depth+1); err != nil {
|
||||||
|
v.SetLen(n)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
@@ -521,13 +528,15 @@ Loop:
|
||||||
|
case StartElement:
|
||||||
|
consumed := false
|
||||||
|
if sv.IsValid() {
|
||||||
|
- consumed, err = d.unmarshalPath(tinfo, sv, nil, &t)
|
||||||
|
+ // unmarshalPath can call unmarshal, so we need to pass the depth through so that
|
||||||
|
+ // we can continue to enforce the maximum recusion limit.
|
||||||
|
+ consumed, err = d.unmarshalPath(tinfo, sv, nil, &t, depth)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !consumed && saveAny.IsValid() {
|
||||||
|
consumed = true
|
||||||
|
- if err := d.unmarshal(saveAny, &t); err != nil {
|
||||||
|
+ if err := d.unmarshal(saveAny, &t, depth+1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -672,7 +681,7 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
|
||||||
|
// The consumed result tells whether XML elements have been consumed
|
||||||
|
// from the Decoder until start's matching end element, or if it's
|
||||||
|
// still untouched because start is uninteresting for sv's fields.
|
||||||
|
-func (d *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) {
|
||||||
|
+func (d *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement, depth int) (consumed bool, err error) {
|
||||||
|
recurse := false
|
||||||
|
Loop:
|
||||||
|
for i := range tinfo.fields {
|
||||||
|
@@ -687,7 +696,7 @@ Loop:
|
||||||
|
}
|
||||||
|
if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local {
|
||||||
|
// It's a perfect match, unmarshal the field.
|
||||||
|
- return true, d.unmarshal(finfo.value(sv, initNilPointers), start)
|
||||||
|
+ return true, d.unmarshal(finfo.value(sv, initNilPointers), start, depth+1)
|
||||||
|
}
|
||||||
|
if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local {
|
||||||
|
// It's a prefix for the field. Break and recurse
|
||||||
|
@@ -716,7 +725,9 @@ Loop:
|
||||||
|
}
|
||||||
|
switch t := tok.(type) {
|
||||||
|
case StartElement:
|
||||||
|
- consumed2, err := d.unmarshalPath(tinfo, sv, parents, &t)
|
||||||
|
+ // the recursion depth of unmarshalPath is limited to the path length specified
|
||||||
|
+ // by the struct field tag, so we don't increment the depth here.
|
||||||
|
+ consumed2, err := d.unmarshalPath(tinfo, sv, parents, &t, depth)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
diff --git a/src/encoding/xml/read_test.go b/src/encoding/xml/read_test.go
|
||||||
|
index 8c2e70fa22e..8c940aefb81 100644
|
||||||
|
--- a/src/encoding/xml/read_test.go
|
||||||
|
+++ b/src/encoding/xml/read_test.go
|
||||||
|
@@ -5,8 +5,11 @@
|
||||||
|
package xml
|
||||||
|
|
||||||
|
import (
|
||||||
|
+ "bytes"
|
||||||
|
+ "errors"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
+ "runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
@@ -1079,3 +1082,32 @@ func TestUnmarshalWhitespaceAttrs(t *testing.T) {
|
||||||
|
t.Fatalf("whitespace attrs: Unmarshal:\nhave: %#+v\nwant: %#+v", v, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestCVE202230633(t *testing.T) {
|
||||||
|
+ if runtime.GOARCH == "wasm" {
|
||||||
|
+ t.Skip("causes memory exhaustion on js/wasm")
|
||||||
|
+ }
|
||||||
|
+ defer func() {
|
||||||
|
+ p := recover()
|
||||||
|
+ if p != nil {
|
||||||
|
+ t.Fatal("Unmarshal panicked")
|
||||||
|
+ }
|
||||||
|
+ }()
|
||||||
|
+ var example struct {
|
||||||
|
+ Things []string
|
||||||
|
+ }
|
||||||
|
+ Unmarshal(bytes.Repeat([]byte("<a>"), 17_000_000), &example)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func TestCVE202228131(t *testing.T) {
|
||||||
|
+ type nested struct {
|
||||||
|
+ Parent *nested `xml:",any"`
|
||||||
|
+ }
|
||||||
|
+ var n nested
|
||||||
|
+ err := Unmarshal(bytes.Repeat([]byte("<a>"), maxUnmarshalDepth+1), &n)
|
||||||
|
+ if err == nil {
|
||||||
|
+ t.Fatal("Unmarshal did not fail")
|
||||||
|
+ } else if !errors.Is(err, errExeceededMaxUnmarshalDepth) {
|
||||||
|
+ t.Fatalf("Unmarshal unexpected error: got %q, want %q", err, errExeceededMaxUnmarshalDepth)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
138
0009-release-branch.go1.17-encoding-gob-add-a-depth-limit.patch
Normal file
138
0009-release-branch.go1.17-encoding-gob-add-a-depth-limit.patch
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
From 8747af9a1098e8fa497441be4c4a79a23de31a98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <bracewell@google.com>
|
||||||
|
Date: Tue, 7 Jun 2022 13:00:43 -0700
|
||||||
|
Subject: [PATCH 05/11] [release-branch.go1.17] encoding/gob: add a depth limit
|
||||||
|
for ignored fields
|
||||||
|
|
||||||
|
Enforce a nesting limit of 10,000 for ignored fields during decoding
|
||||||
|
of messages. This prevents the possibility of triggering stack
|
||||||
|
exhaustion.
|
||||||
|
|
||||||
|
Fixes #53709
|
||||||
|
Updates #53615
|
||||||
|
Fixes CVE-2022-30635
|
||||||
|
|
||||||
|
Change-Id: I05103d06dd5ca3945fcba3c1f5d3b5a645e8fb0f
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1484771
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||||
|
(cherry picked from commit 55e8f938d22bfec29cc9dc9671044c5a41d1ea9c)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417074
|
||||||
|
Run-TryBot: Heschi Kreinick <heschi@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417074
|
||||||
|
---
|
||||||
|
src/encoding/gob/decode.go | 19 ++++++++++++-------
|
||||||
|
src/encoding/gob/gobencdec_test.go | 24 ++++++++++++++++++++++++
|
||||||
|
2 files changed, 36 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/encoding/gob/decode.go b/src/encoding/gob/decode.go
|
||||||
|
index d2f6c749b1b..0e0ec75cccc 100644
|
||||||
|
--- a/src/encoding/gob/decode.go
|
||||||
|
+++ b/src/encoding/gob/decode.go
|
||||||
|
@@ -871,8 +871,13 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg
|
||||||
|
return &op
|
||||||
|
}
|
||||||
|
|
||||||
|
+var maxIgnoreNestingDepth = 10000
|
||||||
|
+
|
||||||
|
// decIgnoreOpFor returns the decoding op for a field that has no destination.
|
||||||
|
-func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp) *decOp {
|
||||||
|
+func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp, depth int) *decOp {
|
||||||
|
+ if depth > maxIgnoreNestingDepth {
|
||||||
|
+ error_(errors.New("invalid nesting depth"))
|
||||||
|
+ }
|
||||||
|
// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
|
||||||
|
// Return the pointer to the op we're already building.
|
||||||
|
if opPtr := inProgress[wireId]; opPtr != nil {
|
||||||
|
@@ -896,7 +901,7 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp)
|
||||||
|
errorf("bad data: undefined type %s", wireId.string())
|
||||||
|
case wire.ArrayT != nil:
|
||||||
|
elemId := wire.ArrayT.Elem
|
||||||
|
- elemOp := dec.decIgnoreOpFor(elemId, inProgress)
|
||||||
|
+ elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
|
||||||
|
op = func(i *decInstr, state *decoderState, value reflect.Value) {
|
||||||
|
state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len)
|
||||||
|
}
|
||||||
|
@@ -904,15 +909,15 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp)
|
||||||
|
case wire.MapT != nil:
|
||||||
|
keyId := dec.wireType[wireId].MapT.Key
|
||||||
|
elemId := dec.wireType[wireId].MapT.Elem
|
||||||
|
- keyOp := dec.decIgnoreOpFor(keyId, inProgress)
|
||||||
|
- elemOp := dec.decIgnoreOpFor(elemId, inProgress)
|
||||||
|
+ keyOp := dec.decIgnoreOpFor(keyId, inProgress, depth+1)
|
||||||
|
+ elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
|
||||||
|
op = func(i *decInstr, state *decoderState, value reflect.Value) {
|
||||||
|
state.dec.ignoreMap(state, *keyOp, *elemOp)
|
||||||
|
}
|
||||||
|
|
||||||
|
case wire.SliceT != nil:
|
||||||
|
elemId := wire.SliceT.Elem
|
||||||
|
- elemOp := dec.decIgnoreOpFor(elemId, inProgress)
|
||||||
|
+ elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
|
||||||
|
op = func(i *decInstr, state *decoderState, value reflect.Value) {
|
||||||
|
state.dec.ignoreSlice(state, *elemOp)
|
||||||
|
}
|
||||||
|
@@ -1073,7 +1078,7 @@ func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *de
|
||||||
|
func (dec *Decoder) compileIgnoreSingle(remoteId typeId) *decEngine {
|
||||||
|
engine := new(decEngine)
|
||||||
|
engine.instr = make([]decInstr, 1) // one item
|
||||||
|
- op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp))
|
||||||
|
+ op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp), 0)
|
||||||
|
ovfl := overflow(dec.typeString(remoteId))
|
||||||
|
engine.instr[0] = decInstr{*op, 0, nil, ovfl}
|
||||||
|
engine.numInstr = 1
|
||||||
|
@@ -1118,7 +1123,7 @@ func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn
|
||||||
|
localField, present := srt.FieldByName(wireField.Name)
|
||||||
|
// TODO(r): anonymous names
|
||||||
|
if !present || !isExported(wireField.Name) {
|
||||||
|
- op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp))
|
||||||
|
+ op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp), 0)
|
||||||
|
engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
diff --git a/src/encoding/gob/gobencdec_test.go b/src/encoding/gob/gobencdec_test.go
|
||||||
|
index 6d2c8db42d0..1b52ecc6c84 100644
|
||||||
|
--- a/src/encoding/gob/gobencdec_test.go
|
||||||
|
+++ b/src/encoding/gob/gobencdec_test.go
|
||||||
|
@@ -12,6 +12,7 @@ import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
+ "reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
@@ -796,3 +797,26 @@ func TestNetIP(t *testing.T) {
|
||||||
|
t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestIngoreDepthLimit(t *testing.T) {
|
||||||
|
+ // We don't test the actual depth limit because it requires building an
|
||||||
|
+ // extremely large message, which takes quite a while.
|
||||||
|
+ oldNestingDepth := maxIgnoreNestingDepth
|
||||||
|
+ maxIgnoreNestingDepth = 100
|
||||||
|
+ defer func() { maxIgnoreNestingDepth = oldNestingDepth }()
|
||||||
|
+ b := new(bytes.Buffer)
|
||||||
|
+ enc := NewEncoder(b)
|
||||||
|
+ typ := reflect.TypeOf(int(0))
|
||||||
|
+ nested := reflect.ArrayOf(1, typ)
|
||||||
|
+ for i := 0; i < 100; i++ {
|
||||||
|
+ nested = reflect.ArrayOf(1, nested)
|
||||||
|
+ }
|
||||||
|
+ badStruct := reflect.New(reflect.StructOf([]reflect.StructField{{Name: "F", Type: nested}}))
|
||||||
|
+ enc.Encode(badStruct.Interface())
|
||||||
|
+ dec := NewDecoder(b)
|
||||||
|
+ var output struct{ Hello int }
|
||||||
|
+ expectedErr := "invalid nesting depth"
|
||||||
|
+ if err := dec.Decode(&output); err == nil || err.Error() != expectedErr {
|
||||||
|
+ t.Errorf("Decode didn't fail with depth limit of 100: want %q, got %q", expectedErr, err)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
From a8d44d0477f2182563e279da115cbc164d639f33 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julie Qiu <julieqiu@google.com>
|
||||||
|
Date: Thu, 23 Jun 2022 23:17:53 +0000
|
||||||
|
Subject: [PATCH 06/11] [release-branch.go1.17] io/fs: fix stack exhaustion in
|
||||||
|
Glob
|
||||||
|
|
||||||
|
A limit is added to the number of path separators allowed by an input to
|
||||||
|
Glob, to prevent stack exhaustion issues.
|
||||||
|
|
||||||
|
Thanks to Juho Nurminen of Mattermost who reported a similar issue in
|
||||||
|
path/filepath.
|
||||||
|
|
||||||
|
Fixes #53719
|
||||||
|
Updates #53415
|
||||||
|
Fixes CVE-2022-30630
|
||||||
|
|
||||||
|
Change-Id: I5a9d02591fed90cd3d52627f5945f1301e53465d
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1497588
|
||||||
|
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||||
|
(cherry picked from commit fdccc5d7bd0f276d0a8de3a818ca844f0bed5d97)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417072
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417072
|
||||||
|
---
|
||||||
|
src/io/fs/glob.go | 14 ++++++++++++--
|
||||||
|
src/io/fs/glob_test.go | 10 ++++++++++
|
||||||
|
2 files changed, 22 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/io/fs/glob.go b/src/io/fs/glob.go
|
||||||
|
index 45d9cb61b96..0e529cd05d1 100644
|
||||||
|
--- a/src/io/fs/glob.go
|
||||||
|
+++ b/src/io/fs/glob.go
|
||||||
|
@@ -31,6 +31,16 @@ type GlobFS interface {
|
||||||
|
// Otherwise, Glob uses ReadDir to traverse the directory tree
|
||||||
|
// and look for matches for the pattern.
|
||||||
|
func Glob(fsys FS, pattern string) (matches []string, err error) {
|
||||||
|
+ return globWithLimit(fsys, pattern, 0)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func globWithLimit(fsys FS, pattern string, depth int) (matches []string, err error) {
|
||||||
|
+ // This limit is added to prevent stack exhaustion issues. See
|
||||||
|
+ // CVE-2022-30630.
|
||||||
|
+ const pathSeparatorsLimit = 10000
|
||||||
|
+ if depth > pathSeparatorsLimit {
|
||||||
|
+ return nil, path.ErrBadPattern
|
||||||
|
+ }
|
||||||
|
if fsys, ok := fsys.(GlobFS); ok {
|
||||||
|
return fsys.Glob(pattern)
|
||||||
|
}
|
||||||
|
@@ -59,9 +69,9 @@ func Glob(fsys FS, pattern string) (matches []string, err error) {
|
||||||
|
}
|
||||||
|
|
||||||
|
var m []string
|
||||||
|
- m, err = Glob(fsys, dir)
|
||||||
|
+ m, err = globWithLimit(fsys, dir, depth+1)
|
||||||
|
if err != nil {
|
||||||
|
- return
|
||||||
|
+ return nil, err
|
||||||
|
}
|
||||||
|
for _, d := range m {
|
||||||
|
matches, err = glob(fsys, d, file, matches)
|
||||||
|
diff --git a/src/io/fs/glob_test.go b/src/io/fs/glob_test.go
|
||||||
|
index f19bebed77f..d052eab3713 100644
|
||||||
|
--- a/src/io/fs/glob_test.go
|
||||||
|
+++ b/src/io/fs/glob_test.go
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
||||||
|
. "io/fs"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
+ "strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -55,6 +56,15 @@ func TestGlobError(t *testing.T) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+func TestCVE202230630(t *testing.T) {
|
||||||
|
+ // Prior to CVE-2022-30630, a stack exhaustion would occur given a large
|
||||||
|
+ // number of separators. There is now a limit of 10,000.
|
||||||
|
+ _, err := Glob(os.DirFS("."), "/*"+strings.Repeat("/", 10001))
|
||||||
|
+ if err != path.ErrBadPattern {
|
||||||
|
+ t.Fatalf("Glob returned err=%v, want %v", err, path.ErrBadPattern)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// contains reports whether vector contains the string s.
|
||||||
|
func contains(vector []string, s string) bool {
|
||||||
|
for _, elem := range vector {
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
From 7b98bf3a8711126c532033ca89647f3b743b58ec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julie Qiu <julieqiu@google.com>
|
||||||
|
Date: Thu, 23 Jun 2022 23:18:56 +0000
|
||||||
|
Subject: [PATCH 07/11] [release-branch.go1.17] path/filepath: fix stack
|
||||||
|
exhaustion in Glob
|
||||||
|
|
||||||
|
A limit is added to the number of path separators allowed by an input to
|
||||||
|
Glob, to prevent stack exhaustion issues.
|
||||||
|
|
||||||
|
Thanks to Juho Nurminen of Mattermost who reported the issue.
|
||||||
|
|
||||||
|
Fixes #53713
|
||||||
|
Updates #53416
|
||||||
|
Fixes CVE-2022-30632
|
||||||
|
|
||||||
|
Change-Id: I1b9fd4faa85411a05dbc91dceae1c0c8eb021f07
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1498176
|
||||||
|
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||||
|
(cherry picked from commit d182a6d1217fd0d04c9babfa9a7ccd3515435c39)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417073
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417073
|
||||||
|
---
|
||||||
|
src/path/filepath/match.go | 12 +++++++++++-
|
||||||
|
src/path/filepath/match_test.go | 10 ++++++++++
|
||||||
|
2 files changed, 21 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/path/filepath/match.go b/src/path/filepath/match.go
|
||||||
|
index c77a26952a6..55ed1d75ae1 100644
|
||||||
|
--- a/src/path/filepath/match.go
|
||||||
|
+++ b/src/path/filepath/match.go
|
||||||
|
@@ -241,6 +241,16 @@ func getEsc(chunk string) (r rune, nchunk string, err error) {
|
||||||
|
// The only possible returned error is ErrBadPattern, when pattern
|
||||||
|
// is malformed.
|
||||||
|
func Glob(pattern string) (matches []string, err error) {
|
||||||
|
+ return globWithLimit(pattern, 0)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func globWithLimit(pattern string, depth int) (matches []string, err error) {
|
||||||
|
+ // This limit is used prevent stack exhaustion issues. See CVE-2022-30632.
|
||||||
|
+ const pathSeparatorsLimit = 10000
|
||||||
|
+ if depth == pathSeparatorsLimit {
|
||||||
|
+ return nil, ErrBadPattern
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Check pattern is well-formed.
|
||||||
|
if _, err := Match(pattern, ""); err != nil {
|
||||||
|
return nil, err
|
||||||
|
@@ -270,7 +280,7 @@ func Glob(pattern string) (matches []string, err error) {
|
||||||
|
}
|
||||||
|
|
||||||
|
var m []string
|
||||||
|
- m, err = Glob(dir)
|
||||||
|
+ m, err = globWithLimit(dir, depth+1)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
diff --git a/src/path/filepath/match_test.go b/src/path/filepath/match_test.go
|
||||||
|
index 375c41a7e9d..d6282596fed 100644
|
||||||
|
--- a/src/path/filepath/match_test.go
|
||||||
|
+++ b/src/path/filepath/match_test.go
|
||||||
|
@@ -155,6 +155,16 @@ func TestGlob(t *testing.T) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+func TestCVE202230632(t *testing.T) {
|
||||||
|
+ // Prior to CVE-2022-30632, this would cause a stack exhaustion given a
|
||||||
|
+ // large number of separators (more than 4,000,000). There is now a limit
|
||||||
|
+ // of 10,000.
|
||||||
|
+ _, err := Glob("/*" + strings.Repeat("/", 10001))
|
||||||
|
+ if err != ErrBadPattern {
|
||||||
|
+ t.Fatalf("Glob returned err=%v, want ErrBadPattern", err)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
func TestGlobError(t *testing.T) {
|
||||||
|
bad := []string{`[]`, `nonexist/[]`}
|
||||||
|
for _, pattern := range bad {
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
From cedbe8f7a1f0d174636e70de68d85499d8025000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <roland@golang.org>
|
||||||
|
Date: Mon, 28 Mar 2022 18:41:26 -0700
|
||||||
|
Subject: [PATCH 08/11] [release-branch.go1.17] encoding/xml: use iterative
|
||||||
|
Skip, rather than recursive
|
||||||
|
|
||||||
|
Prevents exhausting the stack limit in _incredibly_ deeply nested
|
||||||
|
structures.
|
||||||
|
|
||||||
|
Fixes #53711
|
||||||
|
Updates #53614
|
||||||
|
Fixes CVE-2022-28131
|
||||||
|
|
||||||
|
Change-Id: I47db4595ce10cecc29fbd06afce7b299868599e6
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1419912
|
||||||
|
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
(cherry picked from commit 9278cb78443d2b4deb24cbb5b61c9ba5ac688d49)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417068
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417068
|
||||||
|
---
|
||||||
|
src/encoding/xml/read.go | 15 ++++++++-------
|
||||||
|
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
|
||||||
|
index e0ed8b527ce..c77579880cb 100644
|
||||||
|
--- a/src/encoding/xml/read.go
|
||||||
|
+++ b/src/encoding/xml/read.go
|
||||||
|
@@ -743,12 +743,12 @@ Loop:
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip reads tokens until it has consumed the end element
|
||||||
|
-// matching the most recent start element already consumed.
|
||||||
|
-// It recurs if it encounters a start element, so it can be used to
|
||||||
|
-// skip nested structures.
|
||||||
|
+// matching the most recent start element already consumed,
|
||||||
|
+// skipping nested structures.
|
||||||
|
// It returns nil if it finds an end element matching the start
|
||||||
|
// element; otherwise it returns an error describing the problem.
|
||||||
|
func (d *Decoder) Skip() error {
|
||||||
|
+ var depth int64
|
||||||
|
for {
|
||||||
|
tok, err := d.Token()
|
||||||
|
if err != nil {
|
||||||
|
@@ -756,11 +756,12 @@ func (d *Decoder) Skip() error {
|
||||||
|
}
|
||||||
|
switch tok.(type) {
|
||||||
|
case StartElement:
|
||||||
|
- if err := d.Skip(); err != nil {
|
||||||
|
- return err
|
||||||
|
- }
|
||||||
|
+ depth++
|
||||||
|
case EndElement:
|
||||||
|
- return nil
|
||||||
|
+ if depth == 0 {
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+ depth--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
133
0013-release-branch.go1.17-compress-gzip-fix-stack-exhaus.patch
Normal file
133
0013-release-branch.go1.17-compress-gzip-fix-stack-exhaus.patch
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
From 8a445abc7f7e2ed41112f176a169b97859c8d425 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
Date: Fri, 6 May 2022 11:25:06 -0400
|
||||||
|
Subject: [PATCH 09/11] [release-branch.go1.17] compress/gzip: fix stack
|
||||||
|
exhaustion bug in Reader.Read
|
||||||
|
|
||||||
|
Replace recursion with iteration in Reader.Read to avoid stack
|
||||||
|
exhaustion when there are a large number of files.
|
||||||
|
|
||||||
|
Fixes CVE-2022-30631
|
||||||
|
Fixes #53717
|
||||||
|
Updates #53168
|
||||||
|
|
||||||
|
Change-Id: I47d8afe3f2d40b0213ab61431df9b221794dbfe0
|
||||||
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1455673
|
||||||
|
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||||
|
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||||
|
(cherry picked from commit cf498969c8a0bae9d7a24b98fc1f66c824a4775d)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417071
|
||||||
|
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||||
|
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/417071
|
||||||
|
---
|
||||||
|
src/compress/gzip/gunzip.go | 60 +++++++++++++++-----------------
|
||||||
|
src/compress/gzip/gunzip_test.go | 16 +++++++++
|
||||||
|
2 files changed, 45 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/compress/gzip/gunzip.go b/src/compress/gzip/gunzip.go
|
||||||
|
index 924bce10b7c..237b2b928bf 100644
|
||||||
|
--- a/src/compress/gzip/gunzip.go
|
||||||
|
+++ b/src/compress/gzip/gunzip.go
|
||||||
|
@@ -248,42 +248,40 @@ func (z *Reader) Read(p []byte) (n int, err error) {
|
||||||
|
return 0, z.err
|
||||||
|
}
|
||||||
|
|
||||||
|
- n, z.err = z.decompressor.Read(p)
|
||||||
|
- z.digest = crc32.Update(z.digest, crc32.IEEETable, p[:n])
|
||||||
|
- z.size += uint32(n)
|
||||||
|
- if z.err != io.EOF {
|
||||||
|
- // In the normal case we return here.
|
||||||
|
- return n, z.err
|
||||||
|
- }
|
||||||
|
+ for n == 0 {
|
||||||
|
+ n, z.err = z.decompressor.Read(p)
|
||||||
|
+ z.digest = crc32.Update(z.digest, crc32.IEEETable, p[:n])
|
||||||
|
+ z.size += uint32(n)
|
||||||
|
+ if z.err != io.EOF {
|
||||||
|
+ // In the normal case we return here.
|
||||||
|
+ return n, z.err
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- // Finished file; check checksum and size.
|
||||||
|
- if _, err := io.ReadFull(z.r, z.buf[:8]); err != nil {
|
||||||
|
- z.err = noEOF(err)
|
||||||
|
- return n, z.err
|
||||||
|
- }
|
||||||
|
- digest := le.Uint32(z.buf[:4])
|
||||||
|
- size := le.Uint32(z.buf[4:8])
|
||||||
|
- if digest != z.digest || size != z.size {
|
||||||
|
- z.err = ErrChecksum
|
||||||
|
- return n, z.err
|
||||||
|
- }
|
||||||
|
- z.digest, z.size = 0, 0
|
||||||
|
+ // Finished file; check checksum and size.
|
||||||
|
+ if _, err := io.ReadFull(z.r, z.buf[:8]); err != nil {
|
||||||
|
+ z.err = noEOF(err)
|
||||||
|
+ return n, z.err
|
||||||
|
+ }
|
||||||
|
+ digest := le.Uint32(z.buf[:4])
|
||||||
|
+ size := le.Uint32(z.buf[4:8])
|
||||||
|
+ if digest != z.digest || size != z.size {
|
||||||
|
+ z.err = ErrChecksum
|
||||||
|
+ return n, z.err
|
||||||
|
+ }
|
||||||
|
+ z.digest, z.size = 0, 0
|
||||||
|
|
||||||
|
- // File is ok; check if there is another.
|
||||||
|
- if !z.multistream {
|
||||||
|
- return n, io.EOF
|
||||||
|
- }
|
||||||
|
- z.err = nil // Remove io.EOF
|
||||||
|
+ // File is ok; check if there is another.
|
||||||
|
+ if !z.multistream {
|
||||||
|
+ return n, io.EOF
|
||||||
|
+ }
|
||||||
|
+ z.err = nil // Remove io.EOF
|
||||||
|
|
||||||
|
- if _, z.err = z.readHeader(); z.err != nil {
|
||||||
|
- return n, z.err
|
||||||
|
+ if _, z.err = z.readHeader(); z.err != nil {
|
||||||
|
+ return n, z.err
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Read from next file, if necessary.
|
||||||
|
- if n > 0 {
|
||||||
|
- return n, nil
|
||||||
|
- }
|
||||||
|
- return z.Read(p)
|
||||||
|
+ return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the Reader. It does not close the underlying io.Reader.
|
||||||
|
diff --git a/src/compress/gzip/gunzip_test.go b/src/compress/gzip/gunzip_test.go
|
||||||
|
index 17c23e8a9be..6fe8ddcf558 100644
|
||||||
|
--- a/src/compress/gzip/gunzip_test.go
|
||||||
|
+++ b/src/compress/gzip/gunzip_test.go
|
||||||
|
@@ -515,3 +515,19 @@ func TestTruncatedStreams(t *testing.T) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestCVE202230631(t *testing.T) {
|
||||||
|
+ var empty = []byte{0x1f, 0x8b, 0x08, 0x00, 0xa7, 0x8f, 0x43, 0x62, 0x00,
|
||||||
|
+ 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
|
+ r := bytes.NewReader(bytes.Repeat(empty, 4e6))
|
||||||
|
+ z, err := NewReader(r)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatalf("NewReader: got %v, want nil", err)
|
||||||
|
+ }
|
||||||
|
+ // Prior to CVE-2022-30631 fix, this would cause an unrecoverable panic due
|
||||||
|
+ // to stack exhaustion.
|
||||||
|
+ _, err = z.Read(make([]byte, 10))
|
||||||
|
+ if err != io.EOF {
|
||||||
|
+ t.Errorf("Reader.Read: got %v, want %v", err, io.EOF)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
From b2815a72bef3f829c5ac7735feddb034f5501cc0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
Date: Thu, 12 May 2022 14:58:29 -0400
|
||||||
|
Subject: [PATCH 10/11] [release-branch.go1.17] crypto/tls: randomly generate
|
||||||
|
ticket_age_add
|
||||||
|
|
||||||
|
As required by RFC 8446, section 4.6.1, ticket_age_add now holds a
|
||||||
|
random 32-bit value. Before this change, this value was always set
|
||||||
|
to 0.
|
||||||
|
|
||||||
|
This change also documents the reasoning for always setting
|
||||||
|
ticket_nonce to 0. The value ticket_nonce must be unique per
|
||||||
|
connection, but we only ever send one ticket per connection.
|
||||||
|
|
||||||
|
Updates #52814
|
||||||
|
Fixes #52832
|
||||||
|
Fixes CVE-2022-30629
|
||||||
|
|
||||||
|
Change-Id: I6c2fc6ca0376b7b968abd59d6d3d3854c1ab68bb
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/405994
|
||||||
|
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||||
|
Run-TryBot: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
(cherry picked from commit fe4de36198794c447fbd9d7cc2d7199a506c76a5)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/408574
|
||||||
|
Run-TryBot: Roland Shoemaker <roland@golang.org>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/408574
|
||||||
|
---
|
||||||
|
src/crypto/tls/handshake_server_tls13.go | 14 ++++++++++++++
|
||||||
|
1 file changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
|
||||||
|
index 08251b84def..6aa52698a3a 100644
|
||||||
|
--- a/src/crypto/tls/handshake_server_tls13.go
|
||||||
|
+++ b/src/crypto/tls/handshake_server_tls13.go
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/rsa"
|
||||||
|
+ "encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
@@ -741,6 +742,19 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
|
||||||
|
}
|
||||||
|
m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
|
||||||
|
|
||||||
|
+ // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
|
||||||
|
+ // The value is not stored anywhere; we never need to check the ticket age
|
||||||
|
+ // because 0-RTT is not supported.
|
||||||
|
+ ageAdd := make([]byte, 4)
|
||||||
|
+ _, err = hs.c.config.rand().Read(ageAdd)
|
||||||
|
+ if err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
+ m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
|
||||||
|
+
|
||||||
|
+ // ticket_nonce, which must be unique per connection, is always left at
|
||||||
|
+ // zero because we only ever send one ticket per connection.
|
||||||
|
+
|
||||||
|
if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
246
0015-release-branch.go1.17-crypto-rand-properly-handle-la.patch
Normal file
246
0015-release-branch.go1.17-crypto-rand-properly-handle-la.patch
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
From 07a30769186210c1b1e25943824743355c4e50f5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <roland@golang.org>
|
||||||
|
Date: Mon, 25 Apr 2022 19:02:35 -0700
|
||||||
|
Subject: [PATCH 11/11] [release-branch.go1.17] crypto/rand: properly handle
|
||||||
|
large Read on windows
|
||||||
|
|
||||||
|
Use the batched reader to chunk large Read calls on windows to a max of
|
||||||
|
1 << 31 - 1 bytes. This prevents an infinite loop when trying to read
|
||||||
|
more than 1 << 32 -1 bytes, due to how RtlGenRandom works.
|
||||||
|
|
||||||
|
This change moves the batched function from rand_unix.go to rand.go,
|
||||||
|
since it is now needed for both windows and unix implementations.
|
||||||
|
|
||||||
|
Updates #52561
|
||||||
|
Fixes #52932
|
||||||
|
Fixes CVE-2022-30634
|
||||||
|
|
||||||
|
Change-Id: Id98fc4b1427e5cb2132762a445b2aed646a37473
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/402257
|
||||||
|
Run-TryBot: Roland Shoemaker <roland@golang.org>
|
||||||
|
Reviewed-by: Filippo Valsorda <filippo@golang.org>
|
||||||
|
Reviewed-by: Filippo Valsorda <valsorda@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
(cherry picked from commit bb1f4416180511231de6d17a1f2f55c82aafc863)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/406635
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://go-review.googlesource.com/c/go/+/406635
|
||||||
|
---
|
||||||
|
src/crypto/rand/rand.go | 18 ++++++++++++++++++
|
||||||
|
src/crypto/rand/rand_batched.go | 22 ++++++----------------
|
||||||
|
src/crypto/rand/rand_batched_test.go | 21 +++++++++++----------
|
||||||
|
src/crypto/rand/rand_getentropy.go | 6 +++---
|
||||||
|
src/crypto/rand/rand_unix.go | 4 ++--
|
||||||
|
src/crypto/rand/rand_windows.go | 18 ++++++------------
|
||||||
|
6 files changed, 46 insertions(+), 43 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go
|
||||||
|
index fddd1147e6e..f2c276008d7 100644
|
||||||
|
--- a/src/crypto/rand/rand.go
|
||||||
|
+++ b/src/crypto/rand/rand.go
|
||||||
|
@@ -23,3 +23,21 @@ var Reader io.Reader
|
||||||
|
func Read(b []byte) (n int, err error) {
|
||||||
|
return io.ReadFull(Reader, b)
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+// batched returns a function that calls f to populate a []byte by chunking it
|
||||||
|
+// into subslices of, at most, readMax bytes.
|
||||||
|
+func batched(f func([]byte) error, readMax int) func([]byte) error {
|
||||||
|
+ return func(out []byte) error {
|
||||||
|
+ for len(out) > 0 {
|
||||||
|
+ read := len(out)
|
||||||
|
+ if read > readMax {
|
||||||
|
+ read = readMax
|
||||||
|
+ }
|
||||||
|
+ if err := f(out[:read]); err != nil {
|
||||||
|
+ return err
|
||||||
|
+ }
|
||||||
|
+ out = out[read:]
|
||||||
|
+ }
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/crypto/rand/rand_batched.go b/src/crypto/rand/rand_batched.go
|
||||||
|
index d7c5bf3562d..8df715fdd14 100644
|
||||||
|
--- a/src/crypto/rand/rand_batched.go
|
||||||
|
+++ b/src/crypto/rand/rand_batched.go
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
+ "errors"
|
||||||
|
"internal/syscall/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -16,20 +17,6 @@ func init() {
|
||||||
|
altGetRandom = batched(getRandomBatch, maxGetRandomRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
-// batched returns a function that calls f to populate a []byte by chunking it
|
||||||
|
-// into subslices of, at most, readMax bytes.
|
||||||
|
-func batched(f func([]byte) bool, readMax int) func([]byte) bool {
|
||||||
|
- return func(buf []byte) bool {
|
||||||
|
- for len(buf) > readMax {
|
||||||
|
- if !f(buf[:readMax]) {
|
||||||
|
- return false
|
||||||
|
- }
|
||||||
|
- buf = buf[readMax:]
|
||||||
|
- }
|
||||||
|
- return len(buf) == 0 || f(buf)
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
// If the kernel is too old to support the getrandom syscall(),
|
||||||
|
// unix.GetRandom will immediately return ENOSYS and we will then fall back to
|
||||||
|
// reading from /dev/urandom in rand_unix.go. unix.GetRandom caches the ENOSYS
|
||||||
|
@@ -37,7 +24,10 @@ func batched(f func([]byte) bool, readMax int) func([]byte) bool {
|
||||||
|
// If the kernel supports the getrandom() syscall, unix.GetRandom will block
|
||||||
|
// until the kernel has sufficient randomness (as we don't use GRND_NONBLOCK).
|
||||||
|
// In this case, unix.GetRandom will not return an error.
|
||||||
|
-func getRandomBatch(p []byte) (ok bool) {
|
||||||
|
+func getRandomBatch(p []byte) error {
|
||||||
|
n, err := unix.GetRandom(p, 0)
|
||||||
|
- return n == len(p) && err == nil
|
||||||
|
+ if n != len(p) {
|
||||||
|
+ return errors.New("short read")
|
||||||
|
+ }
|
||||||
|
+ return err
|
||||||
|
}
|
||||||
|
diff --git a/src/crypto/rand/rand_batched_test.go b/src/crypto/rand/rand_batched_test.go
|
||||||
|
index 2d20922c825..b56345e50f1 100644
|
||||||
|
--- a/src/crypto/rand/rand_batched_test.go
|
||||||
|
+++ b/src/crypto/rand/rand_batched_test.go
|
||||||
|
@@ -9,20 +9,21 @@ package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
+ "errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBatched(t *testing.T) {
|
||||||
|
- fillBatched := batched(func(p []byte) bool {
|
||||||
|
+ fillBatched := batched(func(p []byte) error {
|
||||||
|
for i := range p {
|
||||||
|
p[i] = byte(i)
|
||||||
|
}
|
||||||
|
- return true
|
||||||
|
+ return nil
|
||||||
|
}, 5)
|
||||||
|
|
||||||
|
p := make([]byte, 13)
|
||||||
|
- if !fillBatched(p) {
|
||||||
|
- t.Fatal("batched function returned false")
|
||||||
|
+ if err := fillBatched(p); err != nil {
|
||||||
|
+ t.Fatalf("batched function returned error: %s", err)
|
||||||
|
}
|
||||||
|
expected := []byte{0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2}
|
||||||
|
if !bytes.Equal(expected, p) {
|
||||||
|
@@ -31,15 +32,15 @@ func TestBatched(t *testing.T) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBatchedError(t *testing.T) {
|
||||||
|
- b := batched(func(p []byte) bool { return false }, 5)
|
||||||
|
- if b(make([]byte, 13)) {
|
||||||
|
- t.Fatal("batched function should have returned false")
|
||||||
|
+ b := batched(func(p []byte) error { return errors.New("") }, 5)
|
||||||
|
+ if b(make([]byte, 13)) == nil {
|
||||||
|
+ t.Fatal("batched function should have returned an error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBatchedEmpty(t *testing.T) {
|
||||||
|
- b := batched(func(p []byte) bool { return false }, 5)
|
||||||
|
- if !b(make([]byte, 0)) {
|
||||||
|
- t.Fatal("empty slice should always return true")
|
||||||
|
+ b := batched(func(p []byte) error { return errors.New("") }, 5)
|
||||||
|
+ if err := b(make([]byte, 0)); err != nil {
|
||||||
|
+ t.Fatalf("empty slice should always return nil: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/crypto/rand/rand_getentropy.go b/src/crypto/rand/rand_getentropy.go
|
||||||
|
index dd725372ad9..b1c19f3d0da 100644
|
||||||
|
--- a/src/crypto/rand/rand_getentropy.go
|
||||||
|
+++ b/src/crypto/rand/rand_getentropy.go
|
||||||
|
@@ -15,7 +15,7 @@ func init() {
|
||||||
|
altGetRandom = getEntropy
|
||||||
|
}
|
||||||
|
|
||||||
|
-func getEntropy(p []byte) (ok bool) {
|
||||||
|
+func getEntropy(p []byte) error {
|
||||||
|
// getentropy(2) returns a maximum of 256 bytes per call
|
||||||
|
for i := 0; i < len(p); i += 256 {
|
||||||
|
end := i + 256
|
||||||
|
@@ -24,8 +24,8 @@ func getEntropy(p []byte) (ok bool) {
|
||||||
|
}
|
||||||
|
err := unix.GetEntropy(p[i:end])
|
||||||
|
if err != nil {
|
||||||
|
- return false
|
||||||
|
+ return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- return true
|
||||||
|
+ return nil
|
||||||
|
}
|
||||||
|
diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go
|
||||||
|
index 81277eb6a5d..3d11159a340 100644
|
||||||
|
--- a/src/crypto/rand/rand_unix.go
|
||||||
|
+++ b/src/crypto/rand/rand_unix.go
|
||||||
|
@@ -46,7 +46,7 @@ type devReader struct {
|
||||||
|
|
||||||
|
// altGetRandom if non-nil specifies an OS-specific function to get
|
||||||
|
// urandom-style randomness.
|
||||||
|
-var altGetRandom func([]byte) (ok bool)
|
||||||
|
+var altGetRandom func([]byte) (err error)
|
||||||
|
|
||||||
|
func warnBlocked() {
|
||||||
|
println("crypto/rand: blocked for 60 seconds waiting to read random data from the kernel")
|
||||||
|
@@ -59,7 +59,7 @@ func (r *devReader) Read(b []byte) (n int, err error) {
|
||||||
|
t := time.AfterFunc(60*time.Second, warnBlocked)
|
||||||
|
defer t.Stop()
|
||||||
|
}
|
||||||
|
- if altGetRandom != nil && r.name == urandomDevice && altGetRandom(b) {
|
||||||
|
+ if altGetRandom != nil && r.name == urandomDevice && altGetRandom(b) == nil {
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
r.mu.Lock()
|
||||||
|
diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go
|
||||||
|
index 7379f1489ad..6c0655c72b6 100644
|
||||||
|
--- a/src/crypto/rand/rand_windows.go
|
||||||
|
+++ b/src/crypto/rand/rand_windows.go
|
||||||
|
@@ -9,7 +9,6 @@ package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"internal/syscall/windows"
|
||||||
|
- "os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() { Reader = &rngReader{} }
|
||||||
|
@@ -17,16 +16,11 @@ func init() { Reader = &rngReader{} }
|
||||||
|
type rngReader struct{}
|
||||||
|
|
||||||
|
func (r *rngReader) Read(b []byte) (n int, err error) {
|
||||||
|
- // RtlGenRandom only accepts 2**32-1 bytes at a time, so truncate.
|
||||||
|
- inputLen := uint32(len(b))
|
||||||
|
-
|
||||||
|
- if inputLen == 0 {
|
||||||
|
- return 0, nil
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- err = windows.RtlGenRandom(b)
|
||||||
|
- if err != nil {
|
||||||
|
- return 0, os.NewSyscallError("RtlGenRandom", err)
|
||||||
|
+ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at
|
||||||
|
+ // most 1<<31-1 bytes at a time so that this works the same on 32-bit
|
||||||
|
+ // and 64-bit systems.
|
||||||
|
+ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil {
|
||||||
|
+ return 0, err
|
||||||
|
}
|
||||||
|
- return int(inputLen), nil
|
||||||
|
+ return len(b), nil
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
125
0016-release-branch.go1.17-math-big-check-buffer-lengths-.patch
Normal file
125
0016-release-branch.go1.17-math-big-check-buffer-lengths-.patch
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
From dc903a8196a831d23e9b6504239e09a9e6bcd98a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Roland Shoemaker <roland@golang.org>
|
||||||
|
Date: Fri, 15 Jul 2022 10:43:44 -0700
|
||||||
|
Subject: [PATCH] [release-branch.go1.17] math/big: check buffer lengths in
|
||||||
|
GobDecode
|
||||||
|
|
||||||
|
In Float.GobDecode and Rat.GobDecode, check buffer sizes before
|
||||||
|
indexing slices.
|
||||||
|
|
||||||
|
Updates #53871
|
||||||
|
Fixes #54094
|
||||||
|
|
||||||
|
Change-Id: I1b652c32c2bc7a0e8aa7620f7be9b2740c568b0a
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/417774
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
Run-TryBot: Roland Shoemaker <roland@golang.org>
|
||||||
|
(cherry picked from commit 055113ef364337607e3e72ed7d48df67fde6fc66)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/419814
|
||||||
|
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||||
|
---
|
||||||
|
src/math/big/floatmarsh.go | 7 +++++++
|
||||||
|
src/math/big/floatmarsh_test.go | 12 ++++++++++++
|
||||||
|
src/math/big/ratmarsh.go | 6 ++++++
|
||||||
|
src/math/big/ratmarsh_test.go | 12 ++++++++++++
|
||||||
|
4 files changed, 37 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/math/big/floatmarsh.go b/src/math/big/floatmarsh.go
|
||||||
|
index d1c1dab069..990e085abe 100644
|
||||||
|
--- a/src/math/big/floatmarsh.go
|
||||||
|
+++ b/src/math/big/floatmarsh.go
|
||||||
|
@@ -8,6 +8,7 @@ package big
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
+ "errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -67,6 +68,9 @@ func (z *Float) GobDecode(buf []byte) error {
|
||||||
|
*z = Float{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
+ if len(buf) < 6 {
|
||||||
|
+ return errors.New("Float.GobDecode: buffer too small")
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if buf[0] != floatGobVersion {
|
||||||
|
return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
|
||||||
|
@@ -83,6 +87,9 @@ func (z *Float) GobDecode(buf []byte) error {
|
||||||
|
z.prec = binary.BigEndian.Uint32(buf[2:])
|
||||||
|
|
||||||
|
if z.form == finite {
|
||||||
|
+ if len(buf) < 10 {
|
||||||
|
+ return errors.New("Float.GobDecode: buffer too small for finite form float")
|
||||||
|
+ }
|
||||||
|
z.exp = int32(binary.BigEndian.Uint32(buf[6:]))
|
||||||
|
z.mant = z.mant.setBytes(buf[10:])
|
||||||
|
}
|
||||||
|
diff --git a/src/math/big/floatmarsh_test.go b/src/math/big/floatmarsh_test.go
|
||||||
|
index c056d78b80..401f45a51f 100644
|
||||||
|
--- a/src/math/big/floatmarsh_test.go
|
||||||
|
+++ b/src/math/big/floatmarsh_test.go
|
||||||
|
@@ -137,3 +137,15 @@ func TestFloatJSONEncoding(t *testing.T) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestFloatGobDecodeShortBuffer(t *testing.T) {
|
||||||
|
+ for _, tc := range [][]byte{
|
||||||
|
+ []byte{0x1, 0x0, 0x0, 0x0},
|
||||||
|
+ []byte{0x1, 0xfa, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
+ } {
|
||||||
|
+ err := NewFloat(0).GobDecode(tc)
|
||||||
|
+ if err == nil {
|
||||||
|
+ t.Error("expected GobDecode to return error for malformed input")
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/math/big/ratmarsh.go b/src/math/big/ratmarsh.go
|
||||||
|
index fbc7b6002d..56102e845b 100644
|
||||||
|
--- a/src/math/big/ratmarsh.go
|
||||||
|
+++ b/src/math/big/ratmarsh.go
|
||||||
|
@@ -45,12 +45,18 @@ func (z *Rat) GobDecode(buf []byte) error {
|
||||||
|
*z = Rat{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
+ if len(buf) < 5 {
|
||||||
|
+ return errors.New("Rat.GobDecode: buffer too small")
|
||||||
|
+ }
|
||||||
|
b := buf[0]
|
||||||
|
if b>>1 != ratGobVersion {
|
||||||
|
return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
|
||||||
|
}
|
||||||
|
const j = 1 + 4
|
||||||
|
i := j + binary.BigEndian.Uint32(buf[j-4:j])
|
||||||
|
+ if len(buf) < int(i) {
|
||||||
|
+ return errors.New("Rat.GobDecode: buffer too small")
|
||||||
|
+ }
|
||||||
|
z.a.neg = b&1 != 0
|
||||||
|
z.a.abs = z.a.abs.setBytes(buf[j:i])
|
||||||
|
z.b.abs = z.b.abs.setBytes(buf[i:])
|
||||||
|
diff --git a/src/math/big/ratmarsh_test.go b/src/math/big/ratmarsh_test.go
|
||||||
|
index 351d109f8d..55a9878bb8 100644
|
||||||
|
--- a/src/math/big/ratmarsh_test.go
|
||||||
|
+++ b/src/math/big/ratmarsh_test.go
|
||||||
|
@@ -123,3 +123,15 @@ func TestRatXMLEncoding(t *testing.T) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestRatGobDecodeShortBuffer(t *testing.T) {
|
||||||
|
+ for _, tc := range [][]byte{
|
||||||
|
+ []byte{0x2},
|
||||||
|
+ []byte{0x2, 0x0, 0x0, 0x0, 0xff},
|
||||||
|
+ } {
|
||||||
|
+ err := NewRat(1, 2).GobDecode(tc)
|
||||||
|
+ if err == nil {
|
||||||
|
+ t.Error("expected GobDecode to return error for malformed input")
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
103
0017-path-filepath-do-not-remove-prefix-.-when-following-.patch
Normal file
103
0017-path-filepath-do-not-remove-prefix-.-when-following-.patch
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
From e903e474f9632a151fff2df3dd3e891395f1a8f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
||||||
|
Date: Fri, 22 Apr 2022 10:07:51 +0900
|
||||||
|
Subject: [PATCH 1/2] path/filepath: do not remove prefix "." when following
|
||||||
|
path contains ":".
|
||||||
|
|
||||||
|
Fixes #52476
|
||||||
|
|
||||||
|
Change-Id: I9eb72ac7dbccd6322d060291f31831dc389eb9bb
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/401595
|
||||||
|
Auto-Submit: Ian Lance Taylor <iant@google.com>
|
||||||
|
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
|
||||||
|
Run-TryBot: Ian Lance Taylor <iant@google.com>
|
||||||
|
Reviewed-by: Ian Lance Taylor <iant@google.com>
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
|
||||||
|
Reference:https://go-review.googlesource.com/c/go/+/401595/
|
||||||
|
Conflict:NA
|
||||||
|
---
|
||||||
|
src/path/filepath/path.go | 14 +++++++++++++-
|
||||||
|
src/path/filepath/path_test.go | 3 +++
|
||||||
|
src/path/filepath/path_windows_test.go | 26 ++++++++++++++++++++++++++
|
||||||
|
3 files changed, 42 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go
|
||||||
|
index b56534dead..8300a32cb1 100644
|
||||||
|
--- a/src/path/filepath/path.go
|
||||||
|
+++ b/src/path/filepath/path.go
|
||||||
|
@@ -117,9 +117,21 @@ func Clean(path string) string {
|
||||||
|
case os.IsPathSeparator(path[r]):
|
||||||
|
// empty path element
|
||||||
|
r++
|
||||||
|
- case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
|
||||||
|
+ case path[r] == '.' && r+1 == n:
|
||||||
|
// . element
|
||||||
|
r++
|
||||||
|
+ case path[r] == '.' && os.IsPathSeparator(path[r+1]):
|
||||||
|
+ // ./ element
|
||||||
|
+ r++
|
||||||
|
+
|
||||||
|
+ for r < len(path) && os.IsPathSeparator(path[r]) {
|
||||||
|
+ r++
|
||||||
|
+ }
|
||||||
|
+ if out.w == 0 && volumeNameLen(path[r:]) > 0 {
|
||||||
|
+ // When joining prefix "." and an absolute path on Windows,
|
||||||
|
+ // the prefix should not be removed.
|
||||||
|
+ out.append('.')
|
||||||
|
+ }
|
||||||
|
case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
|
||||||
|
// .. element: remove to last separator
|
||||||
|
r += 2
|
||||||
|
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
|
||||||
|
index bc5509b49c..ed17a8854d 100644
|
||||||
|
--- a/src/path/filepath/path_test.go
|
||||||
|
+++ b/src/path/filepath/path_test.go
|
||||||
|
@@ -93,6 +93,9 @@ var wincleantests = []PathTest{
|
||||||
|
{`//host/share/foo/../baz`, `\\host\share\baz`},
|
||||||
|
{`\\a\b\..\c`, `\\a\b\c`},
|
||||||
|
{`\\a\b`, `\\a\b`},
|
||||||
|
+ {`.\c:`, `.\c:`},
|
||||||
|
+ {`.\c:\foo`, `.\c:\foo`},
|
||||||
|
+ {`.\c:foo`, `.\c:foo`},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClean(t *testing.T) {
|
||||||
|
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
|
||||||
|
index 76a459ac96..3edafb5a85 100644
|
||||||
|
--- a/src/path/filepath/path_windows_test.go
|
||||||
|
+++ b/src/path/filepath/path_windows_test.go
|
||||||
|
@@ -530,3 +530,29 @@ func TestNTNamespaceSymlink(t *testing.T) {
|
||||||
|
t.Errorf(`EvalSymlinks(%q): got %q, want %q`, filelink, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+func TestIssue52476(t *testing.T) {
|
||||||
|
+ tests := []struct {
|
||||||
|
+ lhs, rhs string
|
||||||
|
+ want string
|
||||||
|
+ }{
|
||||||
|
+ {`..\.`, `C:`, `..\C:`},
|
||||||
|
+ {`..`, `C:`, `..\C:`},
|
||||||
|
+ {`.`, `:`, `:`},
|
||||||
|
+ {`.`, `C:`, `.\C:`},
|
||||||
|
+ {`.`, `C:/a/b/../c`, `.\C:\a\c`},
|
||||||
|
+ {`.`, `\C:`, `.\C:`},
|
||||||
|
+ {`C:\`, `.`, `C:\`},
|
||||||
|
+ {`C:\`, `C:\`, `C:\C:`},
|
||||||
|
+ {`C`, `:`, `C\:`},
|
||||||
|
+ {`\.`, `C:`, `\C:`},
|
||||||
|
+ {`\`, `C:`, `\C:`},
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for _, test := range tests {
|
||||||
|
+ got := filepath.Join(test.lhs, test.rhs)
|
||||||
|
+ if got != test.want {
|
||||||
|
+ t.Errorf(`Join(%q, %q): got %q, want %q`, test.lhs, test.rhs, got, test.want)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
From 66cff0cda766c1533373fabf3bc26fc3397e55d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Damien Neil <dneil@google.com>
|
||||||
|
Date: Tue, 12 Apr 2022 13:38:17 -0700
|
||||||
|
Subject: [PATCH 2/2] [release-branch.go1.17] syscall: check correct group in
|
||||||
|
Faccessat
|
||||||
|
|
||||||
|
The Faccessat call checks the user, group, or other permission bits of a
|
||||||
|
file to see if the calling process can access it. The test to see if the
|
||||||
|
group permissions should be used was made with the wrong group id, using
|
||||||
|
the process's group id rather than the file's group id. Fix this to use
|
||||||
|
the correct group id.
|
||||||
|
|
||||||
|
No test since we cannot easily change file permissions when not running
|
||||||
|
as root and the test is meaningless if running as root.
|
||||||
|
|
||||||
|
For #52313
|
||||||
|
Fixes #52439
|
||||||
|
|
||||||
|
Change-Id: I4e2c84754b0af7830b40fd15dedcbc58374d75ee
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/399539
|
||||||
|
Reviewed-by: Ian Lance Taylor <iant@google.com>
|
||||||
|
Run-TryBot: Ian Lance Taylor <iant@google.com>
|
||||||
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||||
|
(cherry picked from commit f66925e854e71e0c54b581885380a490d7afa30c)
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/401078
|
||||||
|
Auto-Submit: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
Run-TryBot: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
Run-TryBot: Damien Neil <dneil@google.com>
|
||||||
|
Auto-Submit: Damien Neil <dneil@google.com>
|
||||||
|
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
|
||||||
|
|
||||||
|
Reference:https://go-review.googlesource.com/c/go/+/401078/
|
||||||
|
Conflict:NA
|
||||||
|
---
|
||||||
|
src/syscall/syscall_linux.go | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
|
||||||
|
index dfce3d0a4b..3387f3bdc2 100644
|
||||||
|
--- a/src/syscall/syscall_linux.go
|
||||||
|
+++ b/src/syscall/syscall_linux.go
|
||||||
|
@@ -109,7 +109,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
|
||||||
|
gid = Getgid()
|
||||||
|
}
|
||||||
|
|
||||||
|
- if uint32(gid) == st.Gid || isGroupMember(gid) {
|
||||||
|
+ if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
|
||||||
|
fmode = (st.Mode >> 3) & 7
|
||||||
|
} else {
|
||||||
|
fmode = st.Mode & 7
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
||||||
108
golang.spec
108
golang.spec
@ -66,7 +66,7 @@
|
|||||||
|
|
||||||
Name: golang
|
Name: golang
|
||||||
Version: 1.17.3
|
Version: 1.17.3
|
||||||
Release: 1
|
Release: 7
|
||||||
Summary: The Go Programming Language
|
Summary: The Go Programming Language
|
||||||
License: BSD and Public Domain
|
License: BSD and Public Domain
|
||||||
URL: https://golang.org/
|
URL: https://golang.org/
|
||||||
@ -153,10 +153,27 @@ Obsoletes: %{name}-vim < 1.4
|
|||||||
Obsoletes: emacs-%{name} < 1.4
|
Obsoletes: emacs-%{name} < 1.4
|
||||||
Requires: openEuler-rpm-config
|
Requires: openEuler-rpm-config
|
||||||
|
|
||||||
|
Patch6001: 0001-release-branch.go1.17-crypto-elliptic-tolerate-zero-.patch
|
||||||
|
Patch6002: 0002-release-branch.go1.17-encoding-pem-fix-stack-overflo.patch
|
||||||
|
Patch6003: 0003-release-branch.go1.17-syscall-fix-ForkLock-spurious-.patch
|
||||||
|
Patch6004: 0004-backport-cmd-link-mark-unexported-methods-for-plugins.patch
|
||||||
|
Patch6005: 0005-release-branch.go1.17-net-http-preserve-nil-values-i.patch
|
||||||
|
Patch6006: 0006-release-branch.go1.17-go-parser-limit-recursion-dept.patch
|
||||||
|
Patch6007: 0007-release-branch.go1.17-net-http-don-t-strip-whitespac.patch
|
||||||
|
Patch6008: 0008-release-branch.go1.17-encoding-xml-limit-depth-of-ne.patch
|
||||||
|
Patch6009: 0009-release-branch.go1.17-encoding-gob-add-a-depth-limit.patch
|
||||||
|
Patch6010: 0010-release-branch.go1.17-io-fs-fix-stack-exhaustion-in-.patch
|
||||||
|
Patch6011: 0011-release-branch.go1.17-path-filepath-fix-stack-exhaus.patch
|
||||||
|
Patch6012: 0012-release-branch.go1.17-encoding-xml-use-iterative-Ski.patch
|
||||||
|
Patch6013: 0013-release-branch.go1.17-compress-gzip-fix-stack-exhaus.patch
|
||||||
|
Patch6014: 0014-release-branch.go1.17-crypto-tls-randomly-generate-t.patch
|
||||||
|
Patch6015: 0015-release-branch.go1.17-crypto-rand-properly-handle-la.patch
|
||||||
|
Patch6016: 0016-release-branch.go1.17-math-big-check-buffer-lengths-.patch
|
||||||
|
Patch6017: 0017-path-filepath-do-not-remove-prefix-.-when-following-.patch
|
||||||
|
Patch6018: 0018-release-branch.go1.17-syscall-check-correct-group-in.patch
|
||||||
|
|
||||||
ExclusiveArch: %{golang_arches}
|
ExclusiveArch: %{golang_arches}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
%{summary}.
|
%{summary}.
|
||||||
|
|
||||||
@ -388,50 +405,45 @@ fi
|
|||||||
%files devel -f go-tests.list -f go-misc.list -f go-src.list
|
%files devel -f go-tests.list -f go-misc.list -f go-src.list
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Aug 18 2022 hanchao <hanchao47@huawei.com> - 1.17.3-7
|
||||||
|
- Type:CVE
|
||||||
|
- CVE:CVE-2022-29804,CVE-2022-29526
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fix CVE-2022-29804,CVE-2022-29526
|
||||||
|
|
||||||
|
* Mon Aug 8 2022 hanchao <hanchao47@huawei.com> - 1.17.3-6
|
||||||
|
- Type:CVE
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fix CVE-2022-32189
|
||||||
|
|
||||||
|
* Tue Jul 26 2022 hanchao <hanchao47@huawei.com> - 1.17.3-5
|
||||||
|
- Type:CVE
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fix CVE-2022-32148,CVE-2022-1962,CVE-2022-1705,CVE-2022-30633,
|
||||||
|
CVE-2022-30635,CVE-2022-30630,CVE-2022-30632,CVE-2022-28131,
|
||||||
|
CVE-2022-30631,CVE-2022-30629,CVE-2022-30634
|
||||||
|
|
||||||
|
* Tue Jun 28 2022 Bin Hu <hubin73@huawei.com> - 1.17.3-4
|
||||||
|
- Type:bugfix
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:backport patch to fix bug of golang plugin mode
|
||||||
|
|
||||||
|
* Fri May 6 2022 hanchao <hanchao47@huawei.com> - 1.17.3-3
|
||||||
|
- Type:CVE
|
||||||
|
- CVE:CVE-2021-44717
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2021-44717
|
||||||
|
- fix CVE-2021-44717
|
||||||
|
|
||||||
|
* Fri May 6 2022 hanchao <hanchao47@huawei.com> - 1.17.3-2
|
||||||
|
- Type:CVE
|
||||||
|
- CVE:CVE-2022-28327,CVE-2022-24675
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2022-28327,CVE-2022-24675
|
||||||
|
- fix CVE-2022-28327 CVE-2022-24675
|
||||||
|
|
||||||
* Mon Nov 29 2021 chenjiankun <chenjiankun1@huawei.com> - 1.17.3-1
|
* Mon Nov 29 2021 chenjiankun <chenjiankun1@huawei.com> - 1.17.3-1
|
||||||
- upgrade to 1.17.3
|
- upgrade to 1.17.3
|
||||||
|
|
||||||
* Thu Apr 15 2021 lixiang <lixiang172@huawei.com> - 1.15.7-2
|
|
||||||
- speed up build progress
|
|
||||||
|
|
||||||
* Thu Jan 28 2021 xingweizheng <xingweizheng@huawei.com> - 1.15.7-1
|
|
||||||
- upgrade to 1.15.7
|
|
||||||
|
|
||||||
* Mon Dec 7 2020 yangyanchao <yangyanchao6@huawei.com> - 1.15.5-3
|
|
||||||
- Enable Cgo for RISC-V
|
|
||||||
|
|
||||||
* Sat Nov 28 2020 whoisxxx <zhangxuzhou4@huawei.com> - 1.15.5-2
|
|
||||||
- Adate for RISC-V
|
|
||||||
|
|
||||||
* Wed Nov 18 2020 liuzekun <liuzekun@huawei.com> - 1.15.5-1
|
|
||||||
- upgrade to 1.15.5
|
|
||||||
|
|
||||||
* Tue Aug 18 2020 xiadanni <xiadanni1@huawei.com> - 1.13.15-1
|
|
||||||
- upgrade to 1.13.15
|
|
||||||
|
|
||||||
* Fri Jul 31 2020 xiadanni <xiadanni1@huawei.com> - 1.13.14-2
|
|
||||||
- add yaml file
|
|
||||||
|
|
||||||
* Thu Jul 30 2020 xiadanni <xiadanni1@huawei.com> - 1.13.14-1
|
|
||||||
- upgrade to 1.13.14
|
|
||||||
|
|
||||||
* Thu Jul 23 2020 xiadanni <xiadanni1@huawei.com> - 1.13-4.1
|
|
||||||
- bump to 1.13.4
|
|
||||||
|
|
||||||
* Tue May 12 2020 lixiang <lixiang172@huawei.com> - 1.13-3.6
|
|
||||||
- rename tar name and make it same with upstream
|
|
||||||
|
|
||||||
* Tue Mar 24 2020 jingrui <jingrui@huawei.com> - 1.13-3.5
|
|
||||||
- drop hard code cert
|
|
||||||
|
|
||||||
* Mon Mar 23 2020 jingrui <jingrui@huawei.com> - 1.13-3.4
|
|
||||||
- fix CVE-2020-7919
|
|
||||||
|
|
||||||
* Thu Feb 20 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.13-3.2
|
|
||||||
- requires remove mercurial
|
|
||||||
|
|
||||||
* Tue Dec 10 2019 jingrui<jingrui@huawei.com> - 1.13-3.1
|
|
||||||
- upgrade to golang 1.13.3
|
|
||||||
|
|
||||||
* Tue Sep 03 2019 leizhongkai<leizhongkai@huawei.com> - 1.11-1
|
|
||||||
- backport fix CVE-2019-9512 and CVE-2019-9514
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user