aboutsummaryrefslogtreecommitdiff
path: root/src/internal/zstd
diff options
context:
space:
mode:
authoraimuz <mr.imuz@gmail.com>2023-11-18 04:16:04 +0000
committerM Zhuo <mengzhuo1203@gmail.com>2024-01-30 04:10:45 +0000
commit923ab13f9bb6fccc362d5259e2f456abbeda0c51 (patch)
tree88939684915b5a0cf44043b45556b412210f9fb8 /src/internal/zstd
parent4afb155cdf5cd6e8b133174d3369c4db4ea23c77 (diff)
downloadgo-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.go1
-rw-r--r--src/internal/zstd/zstd.go13
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