[FFmpeg-devel] [PATCH] vf_pullup: simplify, fix double free error

wm4 nfxjfg at googlemail.com
Tue Mar 25 15:29:30 CET 2014


On Tue, 25 Mar 2014 15:01:02 +0100
Michael Niedermayer <michaelni at gmx.at> wrote:

> On Tue, Mar 25, 2014 at 01:59:58PM +0100, wm4 wrote:
> > The memory allocation for f->diffs was freed multiple times in some
> > corner cases. Simplify the code so that this doesn't happen. In fact,
> > the body of free_field_queue restores the original MPlayer code.
> > ---
> > Sorry for not providing a reproducible test case, but for me this
> > happened de to a very weird interaction with my application. I
> > suspect this can happen when initializing the filter, but not
> > filtering any frames. But I didn't attempt to confirm this.
> > ---
> >  libavfilter/vf_pullup.c | 21 ++++++++++-----------
> >  1 file changed, 10 insertions(+), 11 deletions(-)
> > 
> > diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c
> > index 58d4d7a..9a3fc05 100644
> > --- a/libavfilter/vf_pullup.c
> > +++ b/libavfilter/vf_pullup.c
> > @@ -126,20 +126,18 @@ static int alloc_metrics(PullupContext *s, PullupField *f)
> >      return 0;
> >  }
> >  
> > -static void free_field_queue(PullupField *head, PullupField **last)
> > +static void free_field_queue(PullupField *head)
> >  {
> >      PullupField *f = head;
> > -    while (f) {
> > +    do {
> > +        if (!f)
> > +            break;
> >          av_free(f->diffs);
> >          av_free(f->combs);
> >          av_free(f->vars);
> > -        if (f == *last) {
> > -            av_freep(last);
> > -            break;
> > -        }
> >          f = f->next;
> > -        av_freep(&f->prev);
> > -    };
> 
> > +        av_free(f->prev);
> 
> this will read freed data
> its a ring, theres no way to free the last element by taking a
> pointer from inside another element of the ring as there is no
> other element for the last one

Does that mean the mplayer code was broken in the first place? I guess
that's why it was different.

> > +    } while (f != head);
> >  }
> >  
> >  static PullupField *make_field_queue(PullupContext *s, int len)
> > @@ -158,14 +156,14 @@ static PullupField *make_field_queue(PullupContext *s, int len)
> >      for (; len > 0; len--) {
> >          f->next = av_mallocz(sizeof(*f->next));
> >          if (!f->next) {
> > -            free_field_queue(head, &f);
> > +            free_field_queue(head);
> 
> this will segfault as f->next is used before checking its null in
> free_field_queue
> 
> [...]

Attached another patch, mostly try&error style.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-vf_pullup-simplify-fix-double-free-error.patch
Type: text/x-patch
Size: 2177 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140325/ac37f5cc/attachment.bin>


More information about the ffmpeg-devel mailing list