]> Cypherpunks repositories - gostls13.git/commitdiff
internal/zstd: avoid panic when windowSize is negative
authoraimuz <mr.imuz@gmail.com>
Sat, 18 Nov 2023 04:16:04 +0000 (04:16 +0000)
committerM Zhuo <mengzhuo1203@gmail.com>
Tue, 30 Jan 2024 04:10:45 +0000 (04:10 +0000)
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>

src/internal/zstd/fuzz_test.go
src/internal/zstd/zstd.go

index 4b5c9961d87aee977ac654a6916d9c67402d8b7c..e945f41241529f829717d4e53fcb4664fe0bb74a 100644 (file)
@@ -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.
index 0230076f5074c5c46ae452e609655164165db142..0370f601cbf45109266a1ab49abdbf13ff134e58 100644 (file)
@@ -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