diff --git a/0001-release-branch.go1.17-crypto-elliptic-tolerate-zero-.patch b/0001-release-branch.go1.17-crypto-elliptic-tolerate-zero-.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f993e03193c56d30da7f26fdb8cbdc9c9e95ebd --- /dev/null +++ b/0001-release-branch.go1.17-crypto-elliptic-tolerate-zero-.patch @@ -0,0 +1,60 @@ +From ad33fdc8f4bce612842d922ca701c3062fe4d4c6 Mon Sep 17 00:00:00 2001 +From: Filippo Valsorda +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 +Reviewed-by: Julie Qiu + +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 + diff --git a/0002-release-branch.go1.17-encoding-pem-fix-stack-overflo.patch b/0002-release-branch.go1.17-encoding-pem-fix-stack-overflo.patch new file mode 100644 index 0000000000000000000000000000000000000000..243596c90ead364fc953a1fd4144479adb812e12 --- /dev/null +++ b/0002-release-branch.go1.17-encoding-pem-fix-stack-overflo.patch @@ -0,0 +1,291 @@ +From baaaf3ce29bf98efc00c2f06c531f2b0186b027b Mon Sep 17 00:00:00 2001 +From: Julie Qiu +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 +Reviewed-by: Filippo Valsorda +(cherry picked from commit 794ea5e828010e8b68493b2fc6d2963263195a02) +Reviewed-on: https://go-review.googlesource.com/c/go/+/399816 +Run-TryBot: Dmitri Shuralyov +Reviewed-by: Dmitri Shuralyov +Reviewed-by: Cherry Mui +TryBot-Result: Gopher Robot + +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 + diff --git a/golang.spec b/golang.spec index 11cc5e2bfaf031a3fd58678fc80b622a265f1132..cb23b1a85fa3aa87d06f6b599fd9baa5e2941bca 100644 --- a/golang.spec +++ b/golang.spec @@ -66,7 +66,7 @@ Name: golang Version: 1.17.3 -Release: 1 +Release: 2 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -153,9 +153,10 @@ Obsoletes: %{name}-vim < 1.4 Obsoletes: emacs-%{name} < 1.4 Requires: openEuler-rpm-config -ExclusiveArch: %{golang_arches} - +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} %description %{summary}. @@ -388,50 +389,12 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Fri May 6 2022 hanchao - 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 - 1.17.3-1 - upgrade to 1.17.3 - -* Thu Apr 15 2021 lixiang - 1.15.7-2 -- speed up build progress - -* Thu Jan 28 2021 xingweizheng - 1.15.7-1 -- upgrade to 1.15.7 - -* Mon Dec 7 2020 yangyanchao - 1.15.5-3 -- Enable Cgo for RISC-V - -* Sat Nov 28 2020 whoisxxx - 1.15.5-2 -- Adate for RISC-V - -* Wed Nov 18 2020 liuzekun - 1.15.5-1 -- upgrade to 1.15.5 - -* Tue Aug 18 2020 xiadanni - 1.13.15-1 -- upgrade to 1.13.15 - -* Fri Jul 31 2020 xiadanni - 1.13.14-2 -- add yaml file - -* Thu Jul 30 2020 xiadanni - 1.13.14-1 -- upgrade to 1.13.14 - -* Thu Jul 23 2020 xiadanni - 1.13-4.1 -- bump to 1.13.4 - -* Tue May 12 2020 lixiang - 1.13-3.6 -- rename tar name and make it same with upstream - -* Tue Mar 24 2020 jingrui - 1.13-3.5 -- drop hard code cert - -* Mon Mar 23 2020 jingrui - 1.13-3.4 -- fix CVE-2020-7919 - -* Thu Feb 20 2020 openEuler Buildteam - 1.13-3.2 -- requires remove mercurial - -* Tue Dec 10 2019 jingrui - 1.13-3.1 -- upgrade to golang 1.13.3 - -* Tue Sep 03 2019 leizhongkai - 1.11-1 -- backport fix CVE-2019-9512 and CVE-2019-9514