diff options
| author | aimuz <mr.imuz@gmail.com> | 2023-11-09 02:30:46 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-11-09 14:30:10 +0000 |
| commit | 291ffcbea6fb8c90681d80c2d708402df00633f9 (patch) | |
| tree | 2c024c2cef0d5b7ec46df0005c765f2710666def /src/internal/zstd | |
| parent | c1a48694530afcf9e378a234de493f9f6de6a364 (diff) | |
| download | go-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.go | 2 | ||||
| -rw-r--r-- | src/internal/zstd/literals.go | 10 |
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 |
