[FFmpeg-trac] #8223(avfilter:new): A potential Use-After-Free bug

FFmpeg trac at avcodec.org
Mon Oct 7 11:04:22 EEST 2019

#8223: A potential Use-After-Free bug
             Reporter:  wurongxin  |                     Type:  defect
               Status:  new        |                 Priority:  normal
            Component:  avfilter   |                  Version:  git-master
             Keywords:             |               Blocked By:
             Blocking:             |  Reproduced by developer:  0
Analyzed by developer:  0          |
 Summary of the bug:
 How to reproduce:
 % ffmpeg -i input ... output
 ffmpeg version
 built on ...
 Patches should be submitted to the ffmpeg-devel mailing list and not this
 bug tracker.

 In the source file
 https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_hwmap.c, at
 Line 114, the call to "av_hwframe_ctx_create_derived" would free
 device->buffer, and device->buffer would be used later at Line 259. This
 lead to a use-after-free bug.

 To see how "av_hwframe_ctx_create_derived" would free device->buffer,
 please see the following code snippet in the source file
 libavutil/hwcontext.c. At Line 828, the copy of the variable
 derived_device_ctx will be created and assigned to the variable dst_ref.
 Since this copy is a shallow copy, dst_ref->buffer is actually the same
 memory location as derived_device_ctx->buffer.  At Line 870,
 dst_ref->buffer can be freed when calling to the function av_buffer_unref.

 798.    int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
 799.            enum AVPixelFormat format,
 800.            AVBufferRef *derived_device_ctx,
 801.            AVBufferRef *source_frame_ctx,
 802.            int flags)
 803.            {
 828.            dst_ref = av_hwframe_ctx_alloc(derived_device_ctx);
 867.    fail:
 868.        if (dst)
 869.            av_buffer_unref(&dst->internal->source_frames);
 870.                av_buffer_unref(&dst_ref);
 871.                return ret;
 872.    }

 The code snippet about the function av_buffer_unref is shown as follows.

 void av_buffer_unref(AVBufferRef **buf)
     if (!buf || !*buf)

     buffer_replace(buf, NULL);

 static void buffer_replace(AVBufferRef **dst, AVBufferRef **src)
     AVBuffer *b;

     b = (*dst)->buffer;

     if (src) {
         **dst = **src;
     } else

     if (atomic_fetch_add_explicit(&b->refcount, -1, memory_order_acq_rel)
 == 1) {
         b->free(b->opaque, b->data);

Ticket URL: <https://trac.ffmpeg.org/ticket/8223>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker

More information about the FFmpeg-trac mailing list