From: aimuz Date: Sat, 18 Nov 2023 04:16:04 +0000 (+0000) Subject: internal/zstd: avoid panic when windowSize is negative X-Git-Tag: go1.23rc1~1350 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=923ab13f9bb6fccc362d5259e2f456abbeda0c51;p=gostls13.git internal/zstd: avoid panic when windowSize is negative This change fixes an edge case in the zstd decompressor where an int conversion could result in a negative window size. Fixes #63979 For #62513 Change-Id: Ie714bf8fb51fa509b310deb8bd2c96bd87b52852 GitHub-Last-Rev: ab0be6578247da896f16d85e102b81994b8ee5c4 GitHub-Pull-Request: golang/go#63980 Reviewed-on: https://go-review.googlesource.com/c/go/+/540415 Reviewed-by: Cherry Mui Run-TryBot: M Zhuo Reviewed-by: Bryan Mills Reviewed-by: M Zhuo TryBot-Result: Gopher Robot --- diff --git a/src/internal/zstd/fuzz_test.go b/src/internal/zstd/fuzz_test.go index 4b5c9961d8..e945f41241 100644 --- a/src/internal/zstd/fuzz_test.go +++ b/src/internal/zstd/fuzz_test.go @@ -25,6 +25,7 @@ var badStrings = []string{ "(\xb5/\xfd00\xec\x00\x00&@\x05\x05A7002\x02\x00\x02\x00\x02\x0000000000000000", "(\xb5/\xfd00\xec\x00\x00V@\x05\x0517002\x02\x00\x02\x00\x02\x0000000000000000", "\x50\x2a\x4d\x18\x02\x00\x00\x00", + "(\xb5/\xfd\xe40000000\xfa20\x000", } // This is a simple fuzzer to see if the decompressor panics. diff --git a/src/internal/zstd/zstd.go b/src/internal/zstd/zstd.go index 0230076f50..0370f601cb 100644 --- a/src/internal/zstd/zstd.go +++ b/src/internal/zstd/zstd.go @@ -237,7 +237,7 @@ retry: // Figure out the maximum amount of data we need to retain // for backreferences. - var windowSize int + var windowSize uint64 if !singleSegment { // Window descriptor. RFC 3.1.1.1.2. windowDescriptor := r.scratch[0] @@ -246,7 +246,7 @@ retry: windowLog := exponent + 10 windowBase := uint64(1) << windowLog windowAdd := (windowBase / 8) * mantissa - windowSize = int(windowBase + windowAdd) + windowSize = windowBase + windowAdd // Default zstd sets limits on the window size. if fuzzing && (windowLog > 31 || windowSize > 1<<27) { @@ -288,12 +288,13 @@ retry: // When Single_Segment_Flag is set, Window_Descriptor is not present. // In this case, Window_Size is Frame_Content_Size. if singleSegment { - windowSize = int(r.remainingFrameSize) + windowSize = r.remainingFrameSize } // RFC 8878 3.1.1.1.1.2. permits us to set an 8M max on window size. - if windowSize > 8<<20 { - windowSize = 8 << 20 + const maxWindowSize = 8 << 20 + if windowSize > maxWindowSize { + windowSize = maxWindowSize } relativeOffset += headerSize @@ -307,7 +308,7 @@ retry: r.repeatedOffset2 = 4 r.repeatedOffset3 = 8 r.huffmanTableBits = 0 - r.window.reset(windowSize) + r.window.reset(int(windowSize)) r.seqTables[0] = nil r.seqTables[1] = nil r.seqTables[2] = nil