fix CVE-2022-28327,CVE-2022-24675

Conflict: NA
Score: CVE-2022-28327:7.5,CVE-2022-24675:7.5
Reference: https://go-review.googlesource.com/c/go/+/397136,https://go-review.googlesource.com/c/go/+/399816
Reason: CVE-2022-28327,CVE-2022-24675
This commit is contained in:
hanchao 2022-05-11 10:39:20 +08:00
parent e2c1a804ad
commit 1145718521
3 changed files with 362 additions and 48 deletions

View File

@ -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

View 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

View File

@ -66,7 +66,7 @@
Name: golang Name: golang
Version: 1.17.3 Version: 1.17.3
Release: 1 Release: 2
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,11 @@ 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
ExclusiveArch: %{golang_arches} ExclusiveArch: %{golang_arches}
%description %description
%{summary}. %{summary}.
@ -388,50 +389,12 @@ 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
* 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