Heap-buffer-overflow in EXIF writer for extra IFD tags
Ruikai Peng
We recently found a cool four-bytes heap-buffer-overflow in FFmpeg's avcodec/exif during the processing of IFDs (Image File Directory). This affects .png , .jpg , .webp , .avif … the formats we use most often. The cause of this bug is very interesting, and I don’t want to spoil it here; I want you to find out.
It’s also a short in-depth dive of FFmpeg internal workings of EXIFs, something we use so often. So even if you’re not really into memory bugs, this can be a cool way to learn how it works under the hood.
This bug wasn’t in FFmpeg long. We happened to catch it about three days after it got introduced in the codebase. You can always trust FFmpeg.
c static int decode_exif_chunk ( AVCodecContext * avctx , PNGDecContext * s , GetByteContext * gb ) { s -> exif_data = av_buffer_alloc ( bytestream2_get_bytes_left ( gb ) ) ; if ( ! s -> exif_data ) return AVERROR ( ENOMEM ) ; bytestream2_get_buffer ( gb , s -> exif_data -> data , s -> exif_data -> size ) ; return 0 ; }
To begin with (in context of PNG), decode_exif_chunk at libavcodec/pngdec.c:763 handles the processing of the exif data in a image. Here is where we allocated the destination of the exif store ( s->exif_data ), in where the PNG decoder stores the exif chunk it read (from gb )_ into.
c if ( s -> exif_data ) { FFSWAP ( AVDictionary * , p -> metadata , s -> frame_metadata ) ; ret = ff_decode_exif_attach_buffer ( avctx , p , & s -> exif_data , AV_EXIF_TIFF_HEADER ) ; FFSWAP ( AVDictionary * , p -> metadata , s -> frame_metadata ) ; if ( ret < 0 ) { av_log ( avctx , AV_LOG_WARNING , "unable to attach EXIF buffer\
" ) ; return ret ; } }
During frame production, that decoder buffer becomes the EXIF payload associated (attaches) with the outputting frame in libavcodec/pngdec.c:1761 , via ff_decode_exif_attach_buffer .
... continue reading