mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-11 08:13:06 +00:00
avcodec/pngdec: bound decompressed zTXt/iCCP size (decompression-bomb guard)
decode_zbuf() inflates zTXt (compressed text) and iCCP (ICC profile) chunk payloads into an AVBPrint created with AV_BPRINT_SIZE_UNLIMITED and never checks the decompressed size. A ~100 KB zTXt chunk of compressed zeros expands to 100 MB; larger ratios or multiple chunks can exhaust memory. Abort with AVERROR_INVALIDDATA once the decompressed output crosses a hard cap (16 MiB). Verified with a crafted PNG (1 KB compressed -> 100 MB decompressed): without the patch the chunk fully decompresses, taking >100 MB; with the patch the inflate loop aborts and the decoder logs "Compressed PNG chunk expands beyond 16777216 bytes" / "Broken zTXt chunk" while the rest of the image decodes normally. Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz Smigielski.
This commit is contained in:
committed by
Leo Izen
co-authored by
Leo Izen
parent
c79dfd29e6
commit
69bdb05f36
@@ -450,6 +450,9 @@ static int png_decode_idat(PNGDecContext *s, GetByteContext *gb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hard cap on decompressed zTXt/iCCP payloads to defeat decompression bombs. */
|
||||
#define PNG_ZBUF_MAX_DECOMPRESSED (16 * 1024 * 1024)
|
||||
|
||||
static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
|
||||
const uint8_t *data_end, void *logctx)
|
||||
{
|
||||
@@ -466,6 +469,13 @@ static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
|
||||
av_bprint_init(bp, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
|
||||
while (zstream->avail_in > 0) {
|
||||
if (bp->len > PNG_ZBUF_MAX_DECOMPRESSED) {
|
||||
av_log(logctx, AV_LOG_ERROR,
|
||||
"Compressed PNG chunk expands beyond %d bytes, aborting\n",
|
||||
PNG_ZBUF_MAX_DECOMPRESSED);
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
av_bprint_get_buffer(bp, 2, &buf, &buf_size);
|
||||
if (buf_size < 2) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
|
||||
Reference in New Issue
Block a user