diff --git a/backport-0010-release-branch.go1.21-net-http-limit-chunked-data-ov.patch b/backport-0010-release-branch.go1.21-net-http-limit-chunked-data-ov.patch new file mode 100644 index 0000000000000000000000000000000000000000..67367a4942d08229540ec978cdc78945705ee85f --- /dev/null +++ b/backport-0010-release-branch.go1.21-net-http-limit-chunked-data-ov.patch @@ -0,0 +1,175 @@ +From 43c0e9116f26416de7454855852eba9083d94d03 Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Tue, 7 Nov 2023 10:47:56 -0800 +Subject: [PATCH 1/2] [release-branch.go1.21] net/http: limit chunked data + overhead + +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. + +Updates #64433 +Fixes #64435 +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/+/2095408 +Run-TryBot: Roland Shoemaker +Reviewed-by: Damien Neil +Reviewed-on: https://go-review.googlesource.com/c/go/+/547356 +Reviewed-by: Dmitri Shuralyov +LUCI-TryBot-Result: Go LUCI +--- + src/net/http/internal/chunked.go | 34 ++++++++++++--- + src/net/http/internal/chunked_test.go | 59 +++++++++++++++++++++++++++ + 2 files changed, 87 insertions(+), 6 deletions(-) + +diff --git a/src/net/http/internal/chunked.go b/src/net/http/internal/chunked.go +index 5a174415dc4..aad8e5aa09e 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,36 @@ 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)) ++ cr.excess = max(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 + } +@@ -140,11 +167,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 5e29a786dd6..b99090c1f8a 100644 +--- a/src/net/http/internal/chunked_test.go ++++ b/src/net/http/internal/chunked_test.go +@@ -239,3 +239,62 @@ func TestChunkEndReadError(t *testing.T) { + t.Errorf("expected %v, got %v", readErr, err) + } + } ++ ++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/backport-0011-Backport-archive-zip-treat-truncated-EOCDR-comment-a.patch b/backport-0011-Backport-archive-zip-treat-truncated-EOCDR-comment-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..55beba5543b0f50020df5f9ac2e93e73f850b63b --- /dev/null +++ b/backport-0011-Backport-archive-zip-treat-truncated-EOCDR-comment-a.patch @@ -0,0 +1,58 @@ +From c69c5c62775d84aa56a43bedaa4fcacbb73d403d Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Tue, 14 May 2024 14:39:10 -0700 +Subject: [PATCH] [Backport] archive/zip: treat truncated EOCDR comment as an + error + +CVE: CVE-2024-24789 +Reference: https://go-review.googlesource.com/c/go/+/588796 + +When scanning for an end of central directory record, +treat an EOCDR signature with a record containing a truncated +comment as an error. Previously, we would skip over the invalid +record and look for another one. Other implementations do not +do this (they either consider this a hard error, or just ignore +the truncated comment). This parser misalignment allowed +presenting entirely different archive contents to Go programs +and other zip decoders. + +For #66869 +Fixes #67554 +Fixes CVE-2024-24789 + +Change-Id: I94e5cb028534bb5704588b8af27f1e22ea49c7c6 +Reviewed-on: https://go-review.googlesource.com/c/go/+/585397 +Reviewed-by: Joseph Tsai +Reviewed-by: Dmitri Shuralyov +LUCI-TryBot-Result: Go LUCI +(cherry picked from commit 33d725e5758bf1fea62e6c77fc70b57a828a49f5) +Reviewed-on: https://go-review.googlesource.com/c/go/+/588796 +Reviewed-by: Matthew Dempsky +Signed-off-by: Ma Chang Wang machangwang@huawei.com +--- + src/archive/zip/reader.go | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go +index 1fde1decc4..20356bde0e 100644 +--- a/src/archive/zip/reader.go ++++ b/src/archive/zip/reader.go +@@ -699,9 +699,13 @@ func findSignatureInBlock(b []byte) int { + if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 { + // n is length of comment + n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8 +- if n+directoryEndLen+i <= len(b) { +- return i ++ if n+directoryEndLen+i > len(b) { ++ // Truncated comment. ++ // Some parsers (such as Info-ZIP) ignore the truncated comment ++ // rather than treating it as a hard error. ++ return -1 + } ++ return i + } + } + return -1 +-- +2.33.0 + diff --git a/golang.spec b/golang.spec index e5ad99bf04ec86768f43e413bac4ced6c0d609c7..f994d26b958bf2dc69ec6158a5e636c29b096936 100644 --- a/golang.spec +++ b/golang.spec @@ -66,7 +66,7 @@ Name: golang Version: 1.21.4 -Release: 12 +Release: 13 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -129,6 +129,8 @@ Patch6006: backport-0006-Backport-net-http-update-bundled-golang.org-x-net-ht.pa Patch6007: backport-0007-Backport-cmd-go-disallow-lto_library-in-LDFLAGS.patch Patch6008: backport-0008-release-branch.go1.21-net-netip-check-if-address-is-v6.patch Patch6009: backport-0009-Backport-cmd-go-internal-vcs-error-out-if-the-reques.patch +Patch6010: backport-0010-release-branch.go1.21-net-http-limit-chunked-data-ov.patch +Patch6011: backport-0011-Backport-archive-zip-treat-truncated-EOCDR-comment-a.patch ExclusiveArch: %{golang_arches} @@ -367,6 +369,12 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Sun Jun 23 2024 hanchao - 1.21.4-13 +- Type:CVE +- CVE:CVE-2023-39326,CVE-2024-24789 +- SUG:NA +- DESC:fix CVE-2023-39326,CVE-2024-24789 + * Fri Jun 21 2024 EulerOSWander <314264452@qq.com> - 1.21.4-12 - fix CVE-2023-45285