Skip to content

Commit

Permalink
internal/zstd: avoid panic when the regenerated size is too small
Browse files Browse the repository at this point in the history
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: 76a7075
GitHub-Pull-Request: #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>
  • Loading branch information
aimuz authored and gopherbot committed Nov 9, 2023
1 parent c1a4869 commit 291ffcb
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/internal/zstd/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 8 additions & 2 deletions src/internal/zstd/literals.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:])
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 291ffcb

Please sign in to comment.