PR #24950 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24950 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24950.patch
Found during triage of the security report Found-by: Joshua Rogers >From a14b790ece0e722a64e35242721b8c9d62b220ea Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 6 Oct 2026 23:06:02 +0200 Subject: [PATCH 1/4] avformat/async: Make abort_request atomic The inner protocol calls async_check_interrupt() from the worker thread without the mutex, while async_close() sets abort_request from the caller thread. Fixes: data race Fixes: SkXYbNIKP9pL Data race Replicated through UnModified FFmpeg with TSAN Found during triage of the security report sYm8PagSr0m4 --- libavformat/async.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavformat/async.c b/libavformat/async.c index 5831b12bd5..ab63cce5db 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -28,6 +28,7 @@ */ #include <inttypes.h> +#include <stdatomic.h> #include <string.h> #include "libavutil/avassert.h" @@ -78,7 +79,7 @@ typedef struct AsyncContext { pthread_mutex_t mutex; pthread_t async_buffer_thread; - int abort_request; + atomic_int abort_request; AVIOInterruptCB interrupt_callback; } AsyncContext; @@ -174,13 +175,13 @@ static int async_check_interrupt(void *arg) URLContext *h = arg; AsyncContext *c = h->priv_data; - if (c->abort_request) + if (atomic_load(&c->abort_request)) return 1; if (ff_check_interrupt(&c->interrupt_callback)) - c->abort_request = 1; + atomic_store(&c->abort_request, 1); - return c->abort_request; + return atomic_load(&c->abort_request); } static void *async_buffer_task(void *arg) @@ -256,6 +257,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** AVIOInterruptCB interrupt_callback = {.callback = async_check_interrupt, .opaque = h}; av_strstart(arg, "async:", &arg); + atomic_init(&c->abort_request, 0); ret = ring_init(&c->ring, BUFFER_CAPACITY, READ_BACK_CAPACITY); if (ret < 0) @@ -322,7 +324,7 @@ static int async_close(URLContext *h) int ret; pthread_mutex_lock(&c->mutex); - c->abort_request = 1; + atomic_store(&c->abort_request, 1); pthread_cond_signal(&c->cond_wakeup_background); pthread_mutex_unlock(&c->mutex); -- 2.52.0 >From e4f769e5e932318ab9850cd32adb5cd8331b2e06 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 6 Oct 2026 23:17:37 +0200 Subject: [PATCH 2/4] fftools/ffmpeg_mux: Avoid signed overflow in the invalid DTS fix-up Fixes: signed integer overflow Fixes: YK9ibCaczocG Fixes: C041.heic Signed integer overflow Replicated through UnModified FFmpeg with UBSAN Found during triage of the security report GL61hVKFlOuU --- fftools/ffmpeg_mux.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 9e7ebd3016..a6991afd87 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -166,9 +166,7 @@ static int mux_fixup_ts(Muxer *mux, MuxStream *ms, AVPacket *pkt) av_log(ost, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64", replacing by guess\n", pkt->dts, pkt->pts); pkt->pts = - pkt->dts = pkt->pts + pkt->dts + ms->last_mux_dts + 1 - - FFMIN3(pkt->pts, pkt->dts, ms->last_mux_dts + 1) - - FFMAX3(pkt->pts, pkt->dts, ms->last_mux_dts + 1); + pkt->dts = av_clip64(ms->last_mux_dts, pkt->pts - 1, pkt->dts - 1) + 1; } if ((ost->type == AVMEDIA_TYPE_AUDIO || ost->type == AVMEDIA_TYPE_VIDEO || ost->type == AVMEDIA_TYPE_SUBTITLE) && pkt->dts != AV_NOPTS_VALUE && -- 2.52.0 >From 7922d0b06801d1cc1cf01f61b0e17042aa74d801 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 6 Oct 2026 23:18:48 +0200 Subject: [PATCH 3/4] avutil/hwcontext: Fail with ENOSYS when a transfer callback is missing This is not a security issue, FFmpeg itself does not create such frames, only an API user setting such a hw_frames_ctx on a frame can. Reported in AISLE-2026-0100-00080 (F7BbuzcmJjqW), not replicated as no OpenHarmony or Android build was available. Found-by: Joshua Rogers <[email protected]> Suggested-by: Joshua Rogers <[email protected]> --- libavutil/hwcontext.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index 83bd7457e8..c9e7d99f1d 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -478,8 +478,10 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) return AVERROR(ENOSYS); } - ret = src_ctx->hw_type->transfer_data_from(&src_ctx->p, dst, src); - if (ret == AVERROR(ENOSYS)) + ret = AVERROR(ENOSYS); + if (src_ctx->hw_type->transfer_data_from) + ret = src_ctx->hw_type->transfer_data_from(&src_ctx->p, dst, src); + if (ret == AVERROR(ENOSYS) && dst_ctx->hw_type->transfer_data_to) ret = dst_ctx->hw_type->transfer_data_to(&dst_ctx->p, dst, src); if (ret < 0) return ret; @@ -487,12 +489,18 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) if (src->hw_frames_ctx) { FFHWFramesContext *ctx = (FFHWFramesContext*)src->hw_frames_ctx->data; + if (!ctx->hw_type->transfer_data_from) + return AVERROR(ENOSYS); + ret = ctx->hw_type->transfer_data_from(&ctx->p, dst, src); if (ret < 0) return ret; } else if (dst->hw_frames_ctx) { FFHWFramesContext *ctx = (FFHWFramesContext*)dst->hw_frames_ctx->data; + if (!ctx->hw_type->transfer_data_to) + return AVERROR(ENOSYS); + ret = ctx->hw_type->transfer_data_to(&ctx->p, dst, src); if (ret < 0) return ret; -- 2.52.0 >From b4492fd7233360ef46fc0fe14bb320b233f5a67b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Wed, 7 Oct 2026 00:04:31 +0200 Subject: [PATCH 4/4] avutil/des: Do not advance a NULL source pointer av_des_crypt() and av_des_mac() accept a NULL src, but the loop still added 8 to it for every block, which is undefined behavior. Pointer arithmetic on NULL Replicated through UnModified FFmpeg with UBSAN Found during triage of the security report f3cEzuDEDwTL --- libavutil/des.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/des.c b/libavutil/des.c index e0e9a86660..ea4f63b9b0 100644 --- a/libavutil/des.c +++ b/libavutil/des.c @@ -313,7 +313,8 @@ static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, iv_val = iv ? dst_val : 0; } AV_WB64(dst, dst_val); - src += 8; + if (src) + src += 8; if (!mac) dst += 8; } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
