diff --git a/src/internal/zstd/fuzz_test.go b/src/internal/zstd/fuzz_test.go index bb6f0a9721f803..b849e124b4d46b 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 b46d668f262e0e..1210fb1a7d51ee 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") } + // Check if the regenerated size is less than 6. + // If it's smaller, this would lead to an out-of-bounds error + // when trying to access the third or fourth stream within our slice during decoding. + // outX = (regeneratedSize + 3) / 4 * (X - 1) + // out4 = (5 + 3) / 4 * 3 > 5 + if regeneratedSize < 6 { + 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:])