]> Cypherpunks.ru repositories - gostls13.git/commitdiff
internal/zstd: avoid panic when the regenerated size is too small
authoraimuz <mr.imuz@gmail.com>
Thu, 9 Nov 2023 02:30:46 +0000 (02:30 +0000)
committerGopher Robot <gobot@golang.org>
Thu, 9 Nov 2023 14:30:10 +0000 (14:30 +0000)
Description in accordance with RFC 8878 3.1.1.3.1.6.

The decompressed size of each stream is equal to (Regenerated_Size+3)/4,
except for the last stream, which may be up to 3 bytes smaller,
to reach a total decompressed size as specified in Regenerated_Size.

Fixes #63824

Change-Id: I5a8b482a995272aa2028a81a4db86c21b1770432
GitHub-Last-Rev: 76a70756bc005a8fcd33b4b6a50fd6c3bf827fb6
GitHub-Pull-Request: golang/go#63959
Reviewed-on: https://go-review.googlesource.com/c/go/+/540055
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Klaus Post <klauspost@gmail.com>
Run-TryBot: Jes Cok <xigua67damn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

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

index 12738519f89607167525c7c7c05de170472fa9ac..4c0e9cf7b9c7cb33effd01ef7b02a1aea68c2797 100644 (file)
@@ -22,6 +22,8 @@ var badStrings = []string{
        "(\xb5/\xfd\x1002000$\x05\x0010\xcc0\xa8100000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "(\xb5/\xfd\x1002000$\x05\x0000\xcc0\xa8100d\x0000001000000000000000000000000000000000000000000000000000000000000000000000000\x000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "(\xb5/\xfd001\x00\x0000000000000000000",
+       "(\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",
 }
 
 // This is a simple fuzzer to see if the decompressor panics.
index b46d668f262e0e2c85d2b0278baaf2bc42b3ec83..11ef859f149673611ec8ab219f22b716badfe67f 100644 (file)
@@ -214,6 +214,14 @@ func (r *Reader) readLiteralsFourStreams(data block, off, totalStreamsSize, rege
        if totalStreamsSize < 6 {
                return nil, r.makeError(off, "total streams size too small for jump table")
        }
+       // RFC 3.1.1.3.1.6.
+       // "The decompressed size of each stream is equal to (Regenerated_Size+3)/4,
+       // except for the last stream, which may be up to 3 bytes smaller,
+       // to reach a total decompressed size as specified in Regenerated_Size."
+       regeneratedStreamSize := (regeneratedSize + 3) / 4
+       if regeneratedSize < regeneratedStreamSize*3 {
+               return nil, r.makeError(off, "regenerated size too small to decode streams")
+       }
 
        streamSize1 := binary.LittleEndian.Uint16(data[off:])
        streamSize2 := binary.LittleEndian.Uint16(data[off+2:])
@@ -262,8 +270,6 @@ func (r *Reader) readLiteralsFourStreams(data block, off, totalStreamsSize, rege
                return nil, err
        }
 
-       regeneratedStreamSize := (regeneratedSize + 3) / 4
-
        out1 := len(outbuf)
        out2 := out1 + regeneratedStreamSize
        out3 := out2 + regeneratedStreamSize