Opened 5 years ago
Closed 5 years ago
#8223 closed defect (needs_more_info)
A potential Use-After-Free bug
Reported by: | wurongxin | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | avfilter |
Version: | git-master | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
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.
- int av_hwframe_ctx_create_derived(AVBufferRef derived_frame_ctx,
- enum AVPixelFormat format,
- AVBufferRef *derived_device_ctx,
- AVBufferRef *source_frame_ctx,
- int flags)
- {
…
- dst_ref = av_hwframe_ctx_alloc(derived_device_ctx);
…
- fail:
- if (dst)
- av_buffer_unref(&dst->internal->source_frames);
- av_buffer_unref(&dst_ref);
- return ret;
- }
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);
}
}