PR #24691 opened by ArthurVasseur-Kyber URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24691 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24691.patch
`av_hwframe_map()` decides whether a call is really an "unmap" of a prior mapping purely by comparing src/dst `hw_frames_ctx` and formats. That heuristic doesn't verify `src->buf[0]` was actually produced by a prior `ff_hwframe_map_create()` call - only that the formats happen to line up. This misfires for callers that attach their own `hw_frames_ctx` to an independently-allocated software frame before calling `av_hwframe_map()` (e.g. `vf_hwmap`'s reverse mode does this unconditionally, with no check that the frame came from its own `get_buffer` hook). When it misfires, `src->buf[0]->data` is read as a `HWMapDescriptor*` and dereferenced, but it's actually plain pixel data a wild pointer read that crashes. This tightens the check: `src->buf[0]`'s underlying `AVBuffer` must have been created by `ff_hwframe_map_create()` (identified by its `free` callback) before it's trusted as a `HWMapDescriptor`. Otherwise it falls through to the normal `map_from`/`map_to` path. **Note this hardens `av_hwframe_map()` defensively but doesn't fix the actual misuse in `vf_hwmap.c` (it still attaches a `hw_frames_ctx` to frames it doesn't own) filing that separately since it needs a proper design decision, not just a crash guard.** >From 562171f28d2f0702b73bfe16ddeed026953b997f Mon Sep 17 00:00:00 2001 From: Arthur Vasseur <[email protected]> Date: Wed, 9 Sep 2026 00:00:00 +0000 Subject: [PATCH] avutil/hwcontext: fix bogus unmap detection in av_hwframe_map av_hwframe_map() treats a call as an "unmap" purely by matching src/dst hw_frames_ctx and pixel formats, without checking that src->buf[0] actually came from ff_hwframe_map_create(). A caller that attaches its own hw_frames_ctx to an independently allocated frame (e.g. vf_hwmap's reverse mode) can satisfy that match by coincidence, so src->buf[0]->data gets misread as a HWMapDescriptor* and dereferenced as garbage - crashes with an XCB capture through "hwmap,scale_vaapi=format=nv12" on VAAPI/Intel Arc. Require src->buf[0]'s AVBuffer to actually be one before trusting it, or fall through to the normal map_from/map_to path. Signed-off-by: Arthur Vasseur <[email protected]> --- libavutil/hwcontext.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index 83bd7457e8..61fc067ca6 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -20,6 +20,7 @@ #include "avassert.h" #include "buffer.h" +#include "buffer_internal.h" #include "common.h" #include "hwcontext.h" #include "hwcontext_internal.h" @@ -807,17 +808,25 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags) (src_frames->source_frames && src_frames->source_frames->data == (uint8_t*)dst_frames)) { - // This is an unmap operation. We don't need to directly - // do anything here other than fill in the original frame, - // because the real unmap will be invoked when the last - // reference to the mapped frame disappears. + // This looks like an unmap, but that alone doesn't prove src + // came from a prior av_hwframe_map() call - a plain frame + // that merely has dst's hw_frames_ctx/sw_format attached + // (e.g. by vf_hwmap's reverse mode) matches the same + // condition. Require src->buf[0] to have actually been + // created by ff_hwframe_map_create() before trusting it. if (!src->buf[0]) { av_log(src_frames, AV_LOG_ERROR, "Invalid mapping " "found when attempting unmap.\n"); return AVERROR(EINVAL); } - hwmap = (HWMapDescriptor*)src->buf[0]->data; - return av_frame_replace(dst, hwmap->source); + if (src->buf[0]->buffer->free == &ff_hwframe_unmap) { + // This is an unmap operation. We don't need to directly + // do anything here other than fill in the original frame, + // because the real unmap will be invoked when the last + // reference to the mapped frame disappears. + hwmap = (HWMapDescriptor*)src->buf[0]->data; + return av_frame_replace(dst, hwmap->source); + } } } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
