diff --git a/0054-CVE-2023-39326-net-http-limit-chunked-data-overhead.patch b/0054-CVE-2023-39326-net-http-limit-chunked-data-overhead.patch new file mode 100644 index 0000000000000000000000000000000000000000..5f07c3c45581e6fd6f5be8938211147db5dd95fa --- /dev/null +++ b/0054-CVE-2023-39326-net-http-limit-chunked-data-overhead.patch @@ -0,0 +1,188 @@ +From 67b897648d6cac32b94b7e98a01588df5c7c59de Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Wed, 8 Nov 2023 02:47:56 +0800 +Subject: [PATCH 1/2] [Backport] net/http: limit chunked data overhead + +Offering: Cloud Core Network +CVE: CVE-2023-39326 +Reference: https://go-review.googlesource.com/c/go/+/547355 +Conflict: NA + +The chunked transfer encoding adds some overhead to +the content transferred. When writing one byte per +chunk, for example, there are five bytes of overhead +per byte of data transferred: "1\r\nX\r\n" to send "X". + +Chunks may include "chunk extensions", +which we skip over and do not use. +For example: "1;chunk extension here\r\nX\r\n". + +A malicious sender can use chunk extensions to add +about 4k of overhead per byte of data. +(The maximum chunk header line size we will accept.) + +Track the amount of overhead read in chunked data, +and produce an error if it seems excessive. + +Note: The upstream does not submit this change to go1.17 according to the rules of MinorReleases. +Corego3.x are based on go1.17.8. Therefore, it need to submit the change to corego3.x. + +Edited-by: machangwang m00509938 + +Updates #64433 +Fixes #64434 +Fixes CVE-2023-39326 + +Change-Id: I40f8d70eb6f9575fb43f506eb19132ccedafcf39 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2076135 +Reviewed-by: Tatiana Bradley +Reviewed-by: Roland Shoemaker +(cherry picked from commit 3473ae72ee66c60744665a24b2fde143e8964d4f) +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2095407 +Run-TryBot: Roland Shoemaker +TryBot-Result: Security TryBots +Reviewed-by: Damien Neil +Reviewed-on: https://go-review.googlesource.com/c/go/+/547355 +Reviewed-by: Dmitri Shuralyov +LUCI-TryBot-Result: Go LUCI +Signed-off-by: Ma Chang Wang machangwang@huawei.com +--- + src/net/http/internal/chunked.go | 36 +++++++++++++--- + src/net/http/internal/chunked_test.go | 59 +++++++++++++++++++++++++++ + 2 files changed, 89 insertions(+), 6 deletions(-) + +diff --git a/src/net/http/internal/chunked.go b/src/net/http/internal/chunked.go +index f06e5725f3..ddbaacbe5d 100644 +--- a/src/net/http/internal/chunked.go ++++ b/src/net/http/internal/chunked.go +@@ -39,7 +39,8 @@ type chunkedReader struct { + n uint64 // unread bytes in chunk + err error + buf [2]byte +- checkEnd bool // whether need to check for \r\n chunk footer ++ checkEnd bool // whether need to check for \r\n chunk footer ++ excess int64 // "excessive" chunk overhead, for malicious sender detection + } + + func (cr *chunkedReader) beginChunk() { +@@ -49,10 +50,38 @@ func (cr *chunkedReader) beginChunk() { + if cr.err != nil { + return + } ++ cr.excess += int64(len(line)) + 2 // header, plus \r\n after the chunk data ++ line = trimTrailingWhitespace(line) ++ line, cr.err = removeChunkExtension(line) ++ if cr.err != nil { ++ return ++ } + cr.n, cr.err = parseHexUint(line) + if cr.err != nil { + return + } ++ // A sender who sends one byte per chunk will send 5 bytes of overhead ++ // for every byte of data. ("1\r\nX\r\n" to send "X".) ++ // We want to allow this, since streaming a byte at a time can be legitimate. ++ // ++ // A sender can use chunk extensions to add arbitrary amounts of additional ++ // data per byte read. ("1;very long extension\r\nX\r\n" to send "X".) ++ // We don't want to disallow extensions (although we discard them), ++ // but we also don't want to allow a sender to reduce the signal/noise ratio ++ // arbitrarily. ++ // ++ // We track the amount of excess overhead read, ++ // and produce an error if it grows too large. ++ // ++ // Currently, we say that we're willing to accept 16 bytes of overhead per chunk, ++ // plus twice the amount of real data in the chunk. ++ cr.excess -= 16 + (2 * int64(cr.n)) ++ if cr.excess < 0 { ++ cr.excess = 0 ++ } ++ if cr.excess > 16*1024 { ++ cr.err = errors.New("chunked encoding contains too much non-data") ++ } + if cr.n == 0 { + cr.err = io.EOF + } +@@ -133,11 +162,6 @@ func readChunkLine(b *bufio.Reader) ([]byte, error) { + if len(p) >= maxLineLength { + return nil, ErrLineTooLong + } +- p = trimTrailingWhitespace(p) +- p, err = removeChunkExtension(p) +- if err != nil { +- return nil, err +- } + return p, nil + } + +diff --git a/src/net/http/internal/chunked_test.go b/src/net/http/internal/chunked_test.go +index 08152ed1e2..5fbeb0855f 100644 +--- a/src/net/http/internal/chunked_test.go ++++ b/src/net/http/internal/chunked_test.go +@@ -211,3 +211,62 @@ func TestChunkReadPartial(t *testing.T) { + } + + } ++ ++func TestChunkReaderTooMuchOverhead(t *testing.T) { ++ // If the sender is sending 100x as many chunk header bytes as chunk data, ++ // we should reject the stream at some point. ++ chunk := []byte("1;") ++ for i := 0; i < 100; i++ { ++ chunk = append(chunk, 'a') // chunk extension ++ } ++ chunk = append(chunk, "\r\nX\r\n"...) ++ const bodylen = 1 << 20 ++ r := NewChunkedReader(&funcReader{f: func(i int) ([]byte, error) { ++ if i < bodylen { ++ return chunk, nil ++ } ++ return []byte("0\r\n"), nil ++ }}) ++ _, err := io.ReadAll(r) ++ if err == nil { ++ t.Fatalf("successfully read body with excessive overhead; want error") ++ } ++} ++ ++func TestChunkReaderByteAtATime(t *testing.T) { ++ // Sending one byte per chunk should not trip the excess-overhead detection. ++ const bodylen = 1 << 20 ++ r := NewChunkedReader(&funcReader{f: func(i int) ([]byte, error) { ++ if i < bodylen { ++ return []byte("1\r\nX\r\n"), nil ++ } ++ return []byte("0\r\n"), nil ++ }}) ++ got, err := io.ReadAll(r) ++ if err != nil { ++ t.Errorf("unexpected error: %v", err) ++ } ++ if len(got) != bodylen { ++ t.Errorf("read %v bytes, want %v", len(got), bodylen) ++ } ++} ++ ++type funcReader struct { ++ f func(iteration int) ([]byte, error) ++ i int ++ b []byte ++ err error ++} ++ ++func (r *funcReader) Read(p []byte) (n int, err error) { ++ if len(r.b) == 0 && r.err == nil { ++ r.b, r.err = r.f(r.i) ++ r.i++ ++ } ++ n = copy(p, r.b) ++ r.b = r.b[n:] ++ if len(r.b) > 0 { ++ return n, nil ++ } ++ return n, r.err ++} +-- +2.33.0 + diff --git a/0055-CVE-2023-45285-cmd-go-internal-vcs-error-out-if-the-reques.patch b/0055-CVE-2023-45285-cmd-go-internal-vcs-error-out-if-the-reques.patch new file mode 100644 index 0000000000000000000000000000000000000000..406de01adc81bac91647681ba1689bd10145bfc4 --- /dev/null +++ b/0055-CVE-2023-45285-cmd-go-internal-vcs-error-out-if-the-reques.patch @@ -0,0 +1,111 @@ +From e70b9fb5d55ff42d408fc9efea67fdb0c671d2b5 Mon Sep 17 00:00:00 2001 +From: "Bryan C. Mills" +Date: Fri, 3 Nov 2023 03:06:35 +0800 +Subject: [PATCH 2/2] [Backport] cmd/go/internal/vcs: error out if the + requested repo does not support a secure protocol + +Offering: Cloud Core Network +CVE: CVE-2023-45285 +Reference: https://go-review.googlesource.com/c/go/+/540335 +Conflict: NA + +Updates #63845. +Fixes #63972. + +Change-Id: If86d6b13d3b55877b35c087112bd76388c9404b8 +Reviewed-on: https://go-review.googlesource.com/c/go/+/539321 +Reviewed-by: Michael Matloob matloob@golang.org +LUCI-TryBot-Result: Go LUCI golang-scoped@luci-project-accounts.iam.gserviceaccount.com +Reviewed-by: Roland Shoemaker roland@golang.org +Auto-Submit: Bryan Mills bcmills@google.com +(cherry picked from commit be26ae18caf7ddffca4073333f80d0d9e76483c3) +Reviewed-on: https://go-review.googlesource.com/c/go/+/540335 +Auto-Submit: Dmitri Shuralyov dmitshur@google.com +Reviewed-by: Dmitri Shuralyov dmitshur@google.com +Signed-off-by: wangbingyao 00557526 wangbingyao5@huawei.com +--- + src/cmd/go/internal/vcs/vcs.go | 25 +++++++++++++---- + .../script/mod_insecure_issue63845.txt | 28 +++++++++++++++++++ + 2 files changed, 47 insertions(+), 6 deletions(-) + create mode 100644 src/cmd/go/testdata/script/mod_insecure_issue63845.txt + +diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go +index 91485f6f74..a890dc87c5 100644 +--- a/src/cmd/go/internal/vcs/vcs.go ++++ b/src/cmd/go/internal/vcs/vcs.go +@@ -892,19 +892,32 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths + if !srv.schemelessRepo { + repoURL = match["repo"] + } else { +- scheme := vcs.Scheme[0] // default to first scheme + repo := match["repo"] +- if vcs.PingCmd != "" { +- // If we know how to test schemes, scan to find one. ++ scheme, err := func() (string, error) { + for _, s := range vcs.Scheme { + if security == web.SecureOnly && !vcs.isSecureScheme(s) { + continue + } +- if vcs.Ping(s, repo) == nil { +- scheme = s +- break ++ ++ // If we know how to ping URL schemes for this VCS, ++ // check that this repo works. ++ // Otherwise, default to the first scheme ++ // that meets the requested security level. ++ if vcs.PingCmd == "" { ++ return s, nil ++ } ++ if err := vcs.Ping(s, repo); err == nil { ++ return s, nil + } + } ++ securityFrag := "" ++ if security == web.SecureOnly { ++ securityFrag = "secure " ++ } ++ return "", fmt.Errorf("no %sprotocol found for repository", securityFrag) ++ }() ++ if err != nil { ++ return nil, err + } + repoURL = scheme + "://" + repo + } +diff --git a/src/cmd/go/testdata/script/mod_insecure_issue63845.txt b/src/cmd/go/testdata/script/mod_insecure_issue63845.txt +new file mode 100644 +index 0000000000..5fa6a4f12b +--- /dev/null ++++ b/src/cmd/go/testdata/script/mod_insecure_issue63845.txt +@@ -0,0 +1,28 @@ ++# Regression test for https://go.dev/issue/63845: ++# If 'git ls-remote' fails for all secure protocols, ++# we should fail instead of falling back to an arbitrary protocol. ++# ++# Note that this test does not use the local vcweb test server ++# (vcs-test.golang.org), because the hook for redirecting to that ++# server bypasses the "ping to determine protocol" logic ++# in cmd/go/internal/vcs. ++ ++[!net] skip ++[!git] skip ++[short] skip 'tries to access a nonexistent external Git repo' ++ ++env GOPRIVATE=golang.org ++env CURLOPT_TIMEOUT_MS=100 ++env GIT_SSH_COMMAND=false ++ ++! go get -x golang.org/nonexist.git@latest ++stderr '^git ls-remote https://golang.org/nonexist$' ++stderr '^git ls-remote git\+ssh://golang.org/nonexist' ++stderr '^git ls-remote ssh://golang.org/nonexist$' ++! stderr 'git://' ++stderr '^go: golang.org/nonexist.git@latest: no secure protocol found for repository$' ++ ++-- go.mod -- ++module example ++ ++go 1.19 +-- +2.33.0 + diff --git a/golang.spec b/golang.spec index 7c971f142e72bbaa6882cf90390ac4c8e2410575..7ca13c133af20c6699c99cd65f97ae18cf45a04e 100644 --- a/golang.spec +++ b/golang.spec @@ -63,7 +63,7 @@ Name: golang Version: 1.17.3 -Release: 25 +Release: 26 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -203,6 +203,8 @@ Patch6050: 0050-Backport-html-template-support-HTML-like-comments-in.patch Patch6051: 0051-Backport-html-template-properly-handle-special-tags-.patch Patch6052: 0052-Backport-cmd-compile-use-absolute-file-name-in-isCgo.patch Patch6053: 0053-CVE-2023-39325-net-http-regenerate-h2_bundle.go.patch +Patch6054: 0054-CVE-2023-39326-net-http-limit-chunked-data-overhead.patch +Patch6055: 0055-CVE-2023-45285-cmd-go-internal-vcs-error-out-if-the-reques.patch ExclusiveArch: %{golang_arches} @@ -441,6 +443,12 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Fri Dec 15 2023 hanchao - 1.17.3-26 +- Type:CVE +- CVE:CVE-2023-39326,CVE-2023-45285 +- SUG:NA +- DESC:fix CVE-2023-39326,CVE-2023-45285 + * Mon Oct 23 2023 hanchao - 1.17.3-25 - Type:CVE - CVE:CVE-2023-39325