[FFmpeg-devel] [PATCH] ff_split_xiph_headers returns broken header_len < 0

Reimar Döffinger Reimar.Doeffinger
Tue Apr 15 20:40:19 CEST 2008


On Tue, Apr 15, 2008 at 08:10:38PM +0200, Michael Niedermayer wrote:
> On Tue, Apr 15, 2008 at 07:44:49PM +0200, Reimar D?ffinger wrote:
> > On Tue, Apr 15, 2008 at 07:38:57PM +0200, Reimar D?ffinger wrote:
> > > On Tue, Apr 15, 2008 at 07:11:12PM +0200, Michael Niedermayer wrote:
> > > > On Tue, Apr 15, 2008 at 06:54:45PM +0200, Reimar D?ffinger wrote:
> > > > > when trying to play http://wdz5.xs4all.nl/~hendrik/mmw-deadzy.ogg with
> > > > > MPlayer (ffplay untested), the vorbis decoder crashes.
> > > > > The reason is that ff_split_xiph_headers does not fail but returns an
> > > > > invalid (negative) header_len[2].
> > > > > Attached patch is one possible fix. Maybe doing a return -1 if this case
> > > > > happens is the better solution, I just like to default to solutions that
> > > > > have a higher chance of still working with broken files (though at least
> > > > > in this case it does not help anyway, the files till does not play).
> > > > 
> > > > I prefer a return -1 (unless doing something else helps some existing file)
> > > > Also your check is insufficient header_len 0/1 still can reach arbitrary
> > > > values, i think this should be fixed more generically. That is checking
> > > > that all are within extradata.
> > > 
> > > I misread one of the existing checks, I think attached patch should
> > > actually work.
> > 
> > With better aligning.
> 
> > Index: libavcodec/xiph.c
> > ===================================================================
> > --- libavcodec/xiph.c	(revision 12807)
> > +++ libavcodec/xiph.c	(working copy)
> > @@ -34,17 +34,24 @@
> >              extradata += header_len[i];
> >          }
> >      } else if (extradata[0] == 2) {
> 
> > +        int overall_len = 0;
> >          for (i=0,j=1; i<2; i++,j++) {
> >              header_len[i] = 0;
> >              for (; j<extradata_size && extradata[j]==0xff; j++) {
> > +                if (overall_len > extradata_size - (0xff + 1))
> > +                    return -1;
> > +                overall_len   += 0xff + 1;
> >                  header_len[i] += 0xff;
> >              }
> >              if (j >= extradata_size)
> >                  return -1;
> >  
> > +            if (overall_len > extradata_size - (extradata[j] + 1))
> > +                return -1;
> > +            overall_len   += extradata[j] + 1;
> >              header_len[i] += extradata[j];
> 
> int overall_len = 1;
> for (i=0,j=1; i<2; i++,j++) {
>     header_len[i] = 0;
>     for (; overall_len <= extradata_size && extradata[j]==0xff; j++) {
>         overall_len   += 0xff + 1;
>         header_len[i] += 0xff;
>     }
>     overall_len   += extradata[j];

I assume you forgot the +1 here?

>     header_len[i] += extradata[j];
> 
>     if (overall_len > extradata_size)
>         return -1;

I didn't do it like this, because it assumes that overall_len will not
overflow, which in turn assumes that extradata will never get close to 2
GB. Though there are lots of ways to avoid that with your suggestion as
well.




More information about the ffmpeg-devel mailing list