diff options
| author | aimuz <mr.imuz@gmail.com> | 2023-11-18 04:16:04 +0000 |
|---|---|---|
| committer | M Zhuo <mengzhuo1203@gmail.com> | 2024-01-30 04:10:45 +0000 |
| commit | 923ab13f9bb6fccc362d5259e2f456abbeda0c51 (patch) | |
| tree | 88939684915b5a0cf44043b45556b412210f9fb8 /src/internal/zstd | |
| parent | 4afb155cdf5cd6e8b133174d3369c4db4ea23c77 (diff) | |
| download | go-923ab13f9bb6fccc362d5259e2f456abbeda0c51.tar.xz | |
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 <cherryyz@google.com>
Run-TryBot: M Zhuo <mengzhuo1203@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: M Zhuo <mengzhuo1203@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/internal/zstd')
| -rw-r--r-- | src/internal/zstd/fuzz_test.go | 1 | ||||
| -rw-r--r-- | src/internal/zstd/zstd.go | 13 |
2 files changed, 8 insertions, 6 deletions
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 |
