From 748912fb3dace33152b88293706f1cfeda342bea Mon Sep 17 00:00:00 2001 From: Ben McClelland Date: Fri, 31 Jan 2025 16:22:25 -0800 Subject: [PATCH] fix: prevent panic with malformed chunk encoding An invalid chunk encoding, or parse errors leading to parsing invalid data can lead to a server panic if the chunk header remaining is determined to be larger than the max buffer size. This was previously seen when the chunk trailer checksums were used by the client without the support from the server side for this encoding. Example panic: panic: runtime error: slice bounds out of range [4088:1024] goroutine 5 [running]: github.com/versity/versitygw/s3api/utils.(*ChunkReader).parseChunkHeaderBytes(0xc0003c4280, {0xc0000e6000?, 0x3000?, 0x423525?}) /home/tester/s3api/utils/chunk-reader.go:242 +0x492 github.com/versity/versitygw/s3api/utils.(*ChunkReader).parseAndRemoveChunkInfo(0xc0003c4280, {0xc0000e6000, 0x3000, 0x8000}) /home/tester/s3api/utils/chunk-reader.go:170 +0x20b github.com/versity/versitygw/s3api/utils.(*ChunkReader).Read(0xc0003c4280, {0xc0000e6000, 0xc0000b41e0?, 0x8000}) /home/tester/s3api/utils/chunk-reader.go:91 +0x11e This fix will validate the data length before copying into the temporary buffer to prevent a panic and instead just return an error. --- s3api/utils/signed-chunk-reader.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/s3api/utils/signed-chunk-reader.go b/s3api/utils/signed-chunk-reader.go index 2b2c6c36..4ece3607 100644 --- a/s3api/utils/signed-chunk-reader.go +++ b/s3api/utils/signed-chunk-reader.go @@ -230,11 +230,14 @@ const ( maxHeaderSize = 1024 ) -// Theis returns the chunk payload size, signature, data start offset, and +// This returns the chunk payload size, signature, data start offset, and // error if any. See the AWS documentation for the chunk header format. The // header[0] byte is expected to be the first byte of the chunk size here. func (cr *ChunkReader) parseChunkHeaderBytes(header []byte) (int64, string, int, error) { stashLen := len(cr.stash) + if stashLen > maxHeaderSize { + return 0, "", 0, errInvalidChunkFormat + } if cr.stash != nil { tmp := make([]byte, maxHeaderSize) copy(tmp, cr.stash)