[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)
return;
buffer_replace(buf, NULL);
}
static void buffer_replace(AVBufferRef **dst, AVBufferRef **src)
{
AVBuffer *b;
b = (*dst)->buffer;
if (src) {
**dst = **src;
av_freep(src);
} else
av_freep(dst);
if (atomic_fetch_add_explicit(&b->refcount, -1, memory_order_acq_rel)
== 1) {
b->free(b->opaque, b->data);
av_freep(&b);
}
}
--
Ticket URL: <https://trac.ffmpeg.org/ticket/8223>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list