[FFmpeg-devel] [PATCH] fix AVI decode crash introduced in r24579

Andrew Wason rectalogic
Fri Aug 27 19:04:12 CEST 2010


ffmpeg r24579 introduced a bug that causes a crash with some AVI
samples (I have 3 samples that cause it, all are AVI with DV and PCM
audio).

r24579 added a call to get_subtitle_pkt() in get_stream_idx(), but for
these samples the audio streams st->priv_data is NULL and
get_subtitle_pkt() crashes when it attempts to use it.

Sample uploaded to /MPlayer/incoming/avidec-crash/dv-pcm-crash.avi

Attached patch adds a check to guard against NULL st->priv_data in
get_subtitle_pkt() and in avi_read_close().


Crash backtrace:

FFplay version SVN-r24953, Copyright (c) 2003-2010 the FFmpeg developers
  built on Aug 27 2010 12:29:46 with gcc 4.2.1 (Apple Inc. build 5664)
  configuration: --enable-debug=gdb3 --disable-optimizations
  libavutil     50.24. 0 / 50.24. 0
  libavcore      0. 6. 0 /  0. 6. 0
  libavcodec    52.87. 0 / 52.87. 0
  libavformat   52.78. 3 / 52.78. 3
  libavdevice   52. 2. 1 / 52. 2. 1
  libavfilter    1.38. 1 /  1.38. 1
  libswscale     0.11. 0 /  0.11. 0
[avi @ 0x10280c200] Estimating duration from bitrate, this may be inaccurate
Input #0, avi, from '/Volumes/Passport/bugs/ffmpeg-avi-pcm/dv-pcm-crash.avi':
  Duration: 00:01:12.87, start: 0.000000, bitrate: 30307 kb/s
    Stream #0.0: Video: dvvideo, yuv411p, 720x480, 28771 kb/s, PAR
10:11 DAR 15:11, 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0.1: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
[ffplay_output @ 0x101b2b000] auto-inserting filter 'auto-inserted
scaler 0' between the filter 'src' and the filter 'out'
[scale @ 0x101b2b290] w:720 h:480 fmt:yuv411p -> w:720 h:480
fmt:yuv420p flags:0x4

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000450
[Switching to process 21503]
0x0000000100028074 in get_subtitle_pkt (s=0x114809000,
next_st=0x102608c10, pkt=0x114790c30) at libavformat/avidec.c:762
762	        if (st->discard < AVDISCARD_ALL && ast->sub_pkt.data) {
(gdb) bt
#0  0x0000000100028074 in get_subtitle_pkt (s=0x114809000,
next_st=0x102608c10, pkt=0x114790c30) at libavformat/avidec.c:762
#1  0x0000000100028619 in avi_read_packet (s=0x114809000,
pkt=0x114790c30) at libavformat/avidec.c:869
#2  0x00000001000c4e7e in av_read_packet (s=0x114809000,
pkt=0x114790c30) at libavformat/utils.c:665
#3  0x00000001000c6822 in av_read_frame_internal (s=0x114809000,
pkt=0x114790d50) at libavformat/utils.c:1105
#4  0x00000001000c6f36 in av_read_frame (s=0x114809000,
pkt=0x114790d50) at libavformat/utils.c:1230
#5  0x00000001000081f3 in decode_thread (arg=0x114642000) at ffplay.c:2640
-------------- next part --------------
Index: libavformat/avidec.c
===================================================================
--- libavformat/avidec.c	(revision 24953)
+++ libavformat/avidec.c	(working copy)
@@ -759,7 +759,7 @@
     for (i=0; i<s->nb_streams; i++) {
         st  = s->streams[i];
         ast = st->priv_data;
-        if (st->discard < AVDISCARD_ALL && ast->sub_pkt.data) {
+        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
             ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q);
             if (ts <= next_ts && ts < ts_min) {
                 ts_min = ts;
@@ -1294,12 +1294,14 @@
         AVStream *st = s->streams[i];
         AVIStream *ast = st->priv_data;
         av_free(st->codec->palctrl);
+        if (ast) {
         if (ast->sub_ctx) {
             av_freep(&ast->sub_ctx->pb);
             av_close_input_stream(ast->sub_ctx);
         }
         av_free(ast->sub_buffer);
         av_free_packet(&ast->sub_pkt);
+        }
     }
 
     if (avi->dv_demux)



More information about the ffmpeg-devel mailing list