Opened 12 years ago

Closed 11 years ago

#1244 closed defect (fixed)

ogg: vorbis_header() leaks memory allocated for packets in private data.

Reported by: Dale Curtis Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: ogg leak
Cc: reimar Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

Memory allocated here:
http://git.videolan.org/?p=ffmpeg.git&a=blob&f=libavformat/oggparsevorbis.c&hb=HEAD#l225

Whenever a corrupt ogg file is parsed, the ogg parser may abort before vorbis parsing completes and fixup_vorbis_headers() is called which normally free's the memory.

It might be possible to create a malicious ogg file which triggers this allocation repeated or with a large os->psize, but at worst it'd be a memory DoS.

Non-obvious on how to fix since the allocation happens in the private data section and the free happens after some assumed subsequent parsing.

Valgrind:
Leak_DefinitelyLost
30 bytes in 1 blocks are definitely lost in loss record 999 of 2,937

posix_memalign (m_replacemalloc/vg_replace_malloc.c:1093)
av_malloc (/out/Debug/../../third_party/ffmpeg/libavutil/mem.c:94)
av_mallocz (/out/Debug/../../third_party/ffmpeg/libavutil/mem.c:186)
vorbis_header (/out/Debug/../../third_party/ffmpeg/libavformat/oggparsevorbis.c:225)
ogg_packet (/out/Debug/../../third_party/ffmpeg/libavformat/oggdec.c:400)
ogg_read_header (/out/Debug/../../third_party/ffmpeg/libavformat/oggdec.c:467)
avformat_open_input (/out/Debug/../../third_party/ffmpeg/libavformat/utils.c:634)
media::FFmpegDemuxer::InitializeTask(media::DemuxerHost*, base::Callback<void ()(media::PipelineStatus)> const&) (/out/Debug/../../media/filters/ffmpeg_demuxer.cc:490)

Attachments (1)

wav.711.ogv (6.6 KB ) - added by Dale Curtis 12 years ago.
Invalid OGV triggering memory leak.

Download all attachments as: .zip

Change History (4)

by Dale Curtis, 12 years ago

Attachment: wav.711.ogv added

Invalid OGV triggering memory leak.

comment:1 by Carl Eugen Hoyos, 12 years ago

Keywords: ogg leak added
Reproduced by developer: set
Status: newopen
$ valgrind --leak-check=full ffmpeg_g -i wav.711.ogv
==14895== Memcheck, a memory error detector.
==14895== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==14895== Using LibVEX rev 1732, a library for dynamic binary translation.
==14895== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==14895== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==14895== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==14895== For more details, rerun with: -v
==14895==
ffmpeg version N-40092-g3bbf3f7 Copyright (c) 2000-2012 the FFmpeg developers
  built on Apr 24 2012 07:56:11 with gcc 4.3.2
  configuration: --cc=/usr/local/gcc-4.3.2/bin/gcc --disable-optimizations
  libavutil      51. 47.100 / 51. 47.100
  libavcodec     54. 15.100 / 54. 15.100
  libavformat    54.  3.100 / 54.  3.100
  libavdevice    53.  4.100 / 53.  4.100
  libavfilter     2. 72.100 /  2. 72.100
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0. 11.100 /  0. 11.100
[vorbis @ 0x4469de0] Extradata missing.
    Last message repeated 1 times
[ogg @ 0x4416480] Could not find codec parameters (Unknown: none)
Input #0, ogg, from 'wav.711.ogv':
  Duration: 00:00:00.09, start: 0.000000, bitrate: 603 kb/s
    Stream #0:0: Data: none
    Stream #0:1: Unknown: none
    Stream #0:2: Audio: vorbis, 8000 Hz, 1 channels, s16, 16 kb/s
At least one output file must be specified
==14895==
==14895== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 3 from 1)
==14895== malloc/free: in use at exit: 30 bytes in 1 blocks.
==14895== malloc/free: 100 allocs, 99 frees, 814,825 bytes allocated.
==14895== For counts of detected errors, rerun with: -v
==14895== searching for pointers to 1 not-freed blocks.
==14895== checked 6,271,528 bytes.
==14895==
==14895== 30 bytes in 1 blocks are definitely lost in loss record 1 of 1
==14895==    at 0x4021A50: memalign (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14895==    by 0x4021AAA: posix_memalign (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14895==    by 0x8737E3E: av_malloc (mem.c:95)
==14895==    by 0x8737FB9: av_mallocz (mem.c:187)
==14895==    by 0x81619C1: vorbis_header (oggparsevorbis.c:225)
==14895==    by 0x815379B: ogg_packet (oggdec.c:394)
==14895==    by 0x8153A4D: ogg_get_headers (oggdec.c:461)
==14895==    by 0x8154069: ogg_read_header (oggdec.c:538)
==14895==    by 0x81B2DF6: avformat_open_input (utils.c:638)
==14895==    by 0x805A59A: opt_input_file (ffmpeg.c:4266)
==14895==    by 0x8061174: parse_option (cmdutils.c:303)
==14895==    by 0x80612BA: parse_options (cmdutils.c:336)
==14895==
==14895== LEAK SUMMARY:
==14895==    definitely lost: 30 bytes in 1 blocks.
==14895==      possibly lost: 0 bytes in 0 blocks.
==14895==    still reachable: 0 bytes in 0 blocks.
==14895==         suppressed: 0 bytes in 0 blocks.
$ valgrind --leak-check=full ffmpeg_g -i wav.711.ogv -f null -
==15205== Memcheck, a memory error detector.
==15205== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==15205== Using LibVEX rev 1732, a library for dynamic binary translation.
==15205== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==15205== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==15205== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==15205== For more details, rerun with: -v
==15205==
ffmpeg version N-40092-g3bbf3f7 Copyright (c) 2000-2012 the FFmpeg developers
  built on Apr 24 2012 07:56:11 with gcc 4.3.2
  configuration: --cc=/usr/local/gcc-4.3.2/bin/gcc --disable-optimizations
  libavutil      51. 47.100 / 51. 47.100
  libavcodec     54. 15.100 / 54. 15.100
  libavformat    54.  3.100 / 54.  3.100
  libavdevice    53.  4.100 / 53.  4.100
  libavfilter     2. 72.100 /  2. 72.100
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0. 11.100 /  0. 11.100
[vorbis @ 0x4469de0] Extradata missing.
    Last message repeated 1 times
[ogg @ 0x4416480] Could not find codec parameters (Unknown: none)
Input #0, ogg, from 'wav.711.ogv':
  Duration: 00:00:00.09, start: 0.000000, bitrate: 603 kb/s
    Stream #0:0: Data: none
    Stream #0:1: Unknown: none
    Stream #0:2: Audio: vorbis, 8000 Hz, 1 channels, s16, 16 kb/s
[vorbis @ 0x4469de0] Extradata missing.
Output #0, null, to 'pipe:':
    Stream #0:0: Audio: pcm_s16le, 8000 Hz, 1 channels, s16, 128 kb/s
Stream mapping:
  Stream #0:2 -> #0:0 (vorbis -> pcm_s16le)
Error while opening decoder for input stream #0:2
==15205==
==15205== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 3 from 1)
==15205== malloc/free: in use at exit: 402 bytes in 3 blocks.
==15205== malloc/free: 136 allocs, 133 frees, 879,592 bytes allocated.
==15205== For counts of detected errors, rerun with: -v
==15205== searching for pointers to 3 not-freed blocks.
==15205== checked 6,271,560 bytes.
==15205==
==15205== 402 bytes in 3 blocks are definitely lost in loss record 1 of 1
==15205==    at 0x4021A50: memalign (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==15205==    by 0x4021AAA: posix_memalign (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==15205==    by 0x8737E3E: av_malloc (mem.c:95)
==15205==    by 0x8737FB9: av_mallocz (mem.c:187)
==15205==    by 0x81619C1: vorbis_header (oggparsevorbis.c:225)
==15205==    by 0x815379B: ogg_packet (oggdec.c:394)
==15205==    by 0x8153A4D: ogg_get_headers (oggdec.c:461)
==15205==    by 0x8154069: ogg_read_header (oggdec.c:538)
==15205==    by 0x81B2DF6: avformat_open_input (utils.c:638)
==15205==    by 0x805A59A: opt_input_file (ffmpeg.c:4266)
==15205==    by 0x8061174: parse_option (cmdutils.c:303)
==15205==    by 0x80612BA: parse_options (cmdutils.c:336)
==15205==
==15205== LEAK SUMMARY:
==15205==    definitely lost: 402 bytes in 3 blocks.
==15205==      possibly lost: 0 bytes in 0 blocks.
==15205==    still reachable: 0 bytes in 0 blocks.
==15205==         suppressed: 0 bytes in 0 blocks.

comment:2 by Carl Eugen Hoyos, 11 years ago

The leak has changed:

$ valgrind --leak-check=full ffmpeg_g -i wav.711.ogv -f null -
==19501== Memcheck, a memory error detector
==19501== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19501== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19501== Command: ffmpeg_g -i wav.711.ogv -f null -
==19501==
ffmpeg version N-48607-gdbf0a90 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jan  7 2013 23:18:39 with gcc 4.7 (SUSE Linux)
  configuration: --enable-gpl --disable-indev=jack
  libavutil      52. 13.100 / 52. 13.100
  libavcodec     54. 86.100 / 54. 86.100
  libavformat    54. 59.106 / 54. 59.106
  libavdevice    54.  3.102 / 54.  3.102
  libavfilter     3. 32.100 /  3. 32.100
  libswscale      2.  1.103 /  2.  1.103
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[ogg @ 0x66c6c20] Multiple fisbone for the same stream is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[ogg @ 0x66c6c20] Header parsing failed for stream 0
[ogg @ 0x66c6c20] Header parsing failed for stream 1
[ogg @ 0x66c6c20] Number of headers (1) mismatch for stream 2
[vorbis @ 0x671adc0] Extradata missing.
    Last message repeated 1 times
[ogg @ 0x66c6c20] Could not find codec parameters for stream 1 (Unknown: none): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Guessed Channel Layout for  Input Stream #0.2 : mono
Input #0, ogg, from 'wav.711.ogv':
  Duration: 00:00:00.09, start: 0.000000, bitrate: 603 kb/s
    Stream #0:0: Data: none
    Stream #0:1: Unknown: none
    Stream #0:2: Audio: vorbis, 8000 Hz, mono, fltp, 16 kb/s
[vorbis @ 0x671adc0] Extradata missing.
Output #0, null, to 'pipe:':
    Stream #0:0: Audio: pcm_s16le, 8000 Hz, mono, s16, 128 kb/s
Stream mapping:
  Stream #0:2 -> #0:0 (vorbis -> pcm_s16le)
Error while opening decoder for input stream #0:2
==19501==
==19501== HEAP SUMMARY:
==19501==     in use at exit: 592 bytes in 2 blocks
==19501==   total heap usage: 396 allocs, 394 frees, 941,113 bytes allocated
==19501==
==19501== 72 bytes in 1 blocks are definitely lost in loss record 1 of 2
==19501==    at 0x4C290FE: memalign (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19501==    by 0x4C291A7: posix_memalign (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19501==    by 0xBBB4E1: av_mallocz (mem.c:92)
==19501==    by 0x9A361C: avcodec_open2 (utils.c:813)
==19501==    by 0x463960: transcode_init (ffmpeg.c:2300)
==19501==    by 0x4516C5: main (ffmpeg.c:3005)
==19501==
==19501== 520 bytes in 1 blocks are definitely lost in loss record 2 of 2
==19501==    at 0x4C290FE: memalign (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19501==    by 0x4C291A7: posix_memalign (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19501==    by 0xBBB369: av_malloc (mem.c:92)
==19501==    by 0x99EFBD: avcodec_alloc_frame (utils.c:692)
==19501==    by 0x42AA45: pcm_encode_init (pcm.c:51)
==19501==    by 0x9A3EB5: avcodec_open2 (utils.c:1030)
==19501==    by 0x463960: transcode_init (ffmpeg.c:2300)
==19501==    by 0x4516C5: main (ffmpeg.c:3005)
==19501==
==19501== LEAK SUMMARY:
==19501==    definitely lost: 592 bytes in 2 blocks
==19501==    indirectly lost: 0 bytes in 0 blocks
==19501==      possibly lost: 0 bytes in 0 blocks
==19501==    still reachable: 0 bytes in 0 blocks
==19501==         suppressed: 0 bytes in 0 blocks
==19501==
==19501== For counts of detected and suppressed errors, rerun with: -v
==19501== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

comment:3 by Carl Eugen Hoyos, 11 years ago

Resolution: fixed
Status: openclosed

The original leak was fixed by Luca Barbato in January, the remaining leak (in ffmpeg) was a duplicate of ticket #1546.

Note: See TracTickets for help on using tickets.