diff mbox series

[FFmpeg-devel,03/11] avcodec/pngdec: Do not pass AVFrame into global header decode

Message ID 20230416164830.15664-3-michael@niedermayer.cc
State Accepted
Commit d31d4f32283f765c79d6e127d31ee2c37a0acef7
Headers show
Series [FFmpeg-devel,01/11] avcodec/adpcm: Fix integer overflow in intermediate in ADPCM_XMD | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Michael Niedermayer April 16, 2023, 4:48 p.m. UTC
The global header should not contain a frame, and decoding it
would result in leaks

Fixes: memleak
Fixes: 45982/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APNG_fuzzer-6603443149340672

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/pngdec.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 679cb8c2281..5dc36d400c2 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -734,6 +734,8 @@  static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
     int ret;
     size_t byte_depth = s->bit_depth > 8 ? 2 : 1;
 
+    if (!p)
+        return AVERROR_INVALIDDATA;
     if (!(s->hdr_state & PNG_IHDR)) {
         av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
         return AVERROR_INVALIDDATA;
@@ -1515,6 +1517,9 @@  static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
     }
 exit_loop:
 
+    if (!p)
+        return AVERROR_INVALIDDATA;
+
     if (avctx->codec_id == AV_CODEC_ID_PNG &&
         avctx->skip_frame == AVDISCARD_ALL) {
         return 0;
@@ -1727,7 +1732,7 @@  static int decode_frame_apng(AVCodecContext *avctx, AVFrame *p,
         if ((ret = inflateReset(&s->zstream.zstream)) != Z_OK)
             return AVERROR_EXTERNAL;
         bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
-        if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+        if ((ret = decode_frame_common(avctx, s, NULL, avpkt)) < 0)
             return ret;
     }