aboutsummaryrefslogtreecommitdiff
path: root/src/internal/zstd
diff options
context:
space:
mode:
authoraimuz <mr.imuz@gmail.com>2023-11-09 02:30:46 +0000
committerGopher Robot <gobot@golang.org>2023-11-09 14:30:10 +0000
commit291ffcbea6fb8c90681d80c2d708402df00633f9 (patch)
tree2c024c2cef0d5b7ec46df0005c765f2710666def /src/internal/zstd
parentc1a48694530afcf9e378a234de493f9f6de6a364 (diff)
downloadgo-291ffcbea6fb8c90681d80c2d708402df00633f9.tar.xz
internal/zstd: avoid panic when the regenerated size is too small
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>
Diffstat (limited to 'src/internal/zstd')
-rw-r--r--src/internal/zstd/fuzz_test.go2
-rw-r--r--src/internal/zstd/literals.go10
2 files changed, 10 insertions, 2 deletions
diff --git a/src/internal/zstd/fuzz_test.go b/src/internal/zstd/fuzz_test.go
index 12738519f8..4c0e9cf7b9 100644
--- a/src/internal/zstd/fuzz_test.go
+++ b/src/internal/zstd/fuzz_test.go
@@ -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.
diff --git a/src/internal/zstd/literals.go b/src/internal/zstd/literals.go
index b46d668f26..11ef859f14 100644
--- a/src/internal/zstd/literals.go
+++ b/src/internal/zstd/literals.go
@@ -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