[FFmpeg-devel] [PATCH] FLAC decoder segfault reading metadata

Justin Ruggles justinruggles
Mon Oct 1 05:04:00 CEST 2007


Hello,

While working on the other FLAC decoder bug, I found this similar one. 
Currently, the decoder reads past the end of the GetBitContext buffer if 
the metadata is cut off.  This can lead to a segfault or infinite loop.

I was able to trigger a segfault by creating a FLAC file with 2 large 
metadata blocks.  If you want to duplicate it, use:
flac test.wav -o test.flac
metaflac --dont-use-padding --remove-all test.flac
metaflac --add-padding=100000 test.flac
metaflac --add-padding=100000 test.flac

I've also uploaded a sample to MPlayer/incoming as black-2-pad.flac

$ gdb ./ffmpeg_g
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain 
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) run -debug 1 -i black-2-pad.flac
Starting program: /home/justin/src/ffmpeg/ffmpeg_g -debug 1 -i 
black-2-pad.flac
FFmpeg version SVN-r10629, Copyright (c) 2000-2007 Fabrice Bellard, et al.
   configuration: --disable-ffserver --disable-vhook
   libavutil version: 49.5.0
   libavcodec version: 51.44.0
   libavformat version: 51.14.0
   built on Sep 30 2007 00:26:51, gcc: 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
[flac @ 0x849bf90]STREAM HEADER
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 34
[flac @ 0x849bf90]  Blocksize: 4096 .. 4096 (0)
[flac @ 0x849bf90]  Framesize: 1554 .. 10158
[flac @ 0x849bf90]  Samplerate: 44100
[flac @ 0x849bf90]  Channels: 2
[flac @ 0x849bf90]  Bits: 16
[flac @ 0x849bf90] metadata block: flag = 0, type = 1, size = 100000
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 16640
[flac @ 0x849bf90]  Blocksize: 0 .. 43181 (0)
[flac @ 0x849bf90]  Framesize: 6097128 .. 11951368
[flac @ 0x849bf90]  Samplerate: 0
[flac @ 0x849bf90]  Channels: 1
[flac @ 0x849bf90]  Bits: 1
[flac @ 0x849bf90] metadata block: flag = 0, type = 0, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 25, size = 0
[flac @ 0x849bf90] metadata block: flag = 0, type = 80, size = 12708535

Program received signal SIGSEGV, Segmentation fault.
0x0818eff0 in metadata_parse (s=0x85c2a20) at bitstream.h:694
694         result<<= (index&0x07);
(gdb) bt
#0  0x0818eff0 in metadata_parse (s=0x85c2a20) at bitstream.h:694
#1  0x0818f2c0 in flac_decode_frame (avctx=0x85a5cc0, data=0x85e5e00,
     data_size=0xbfe18540, buf=0x85e5960 "", buf_size=<value optimized out>)
     at flac.c:628
#2  0x080e8bb0 in avcodec_decode_audio2 (avctx=0x85a5cc0, 
samples=0x85e5e00,
     frame_size_ptr=0xbfe18540, buf=0x85e5960 "", buf_size=1024) at 
utils.c:970
#3  0x0805d899 in av_find_stream_info (ic=0x859cbd0) at utils.c:1671
#4  0x0804b915 in opt_input_file (filename=0xbfe1a9dc "black-2-pad.flac")
     at ffmpeg.c:2598
#5  0x08054bd9 in parse_options (argc=5, argv=0xbfe19684, 
options=0x83efda0,
     parse_arg_function=0x804c720 <opt_output_file>) at cmdutils.c:115
#6  0x08051c3b in main (argc=5, argv=0xbfe19684) at ffmpeg.c:3859
(gdb)


The attached patch fixes the problem by adding several checks.  First, 
the streaminfo block can only occur once and must be 34 bytes.  For 
other block types, the remaining size of the buffer is checked before 
attempting to skip the block.  For additional safety, I've added checks 
for invalid streaminfo values.

-Justin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ffmpeg-flac-fix-meta.diff
Type: text/x-patch
Size: 2312 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070930/8d1f61b6/attachment.bin>



More information about the ffmpeg-devel mailing list