PR #24407 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24407 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24407.patch
use after free / double free / segv >From 8a41b5aa0c572e46b7647c72b95be7ae104a313c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sun, 6 Sep 2026 14:39:12 +0200 Subject: [PATCH 1/3] avcodec/vvc/dec: free the tabs when pic_arrays_init() fails Fixes: SEGV / dereference of uninitialized memory Fixes: poc.266 / poc.c Fixes: XjGK97xKVd0y Found-by: agent00712 <[email protected]> --- libavcodec/vvc/dec.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c index 926288e07b..d306fb0bf1 100644 --- a/libavcodec/vvc/dec.c +++ b/libavcodec/vvc/dec.c @@ -369,13 +369,11 @@ static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc) const VVCPPS *pps = fc->ps.pps; const int ctu_count = pps->ctb_count; const int pic_size_in_min_pu = pps->min_pu_width * pps->min_pu_height; - int ret; free_cus(fc); - ret = frame_context_for_each_tl(fc, tl_create); - if (ret < 0) - return ret; + if (frame_context_for_each_tl(fc, tl_create) < 0) + goto fail; // for error handling case, we may call free_cus before VVC_TASK_STAGE_INIT, so we need to set cus to 0 here memset(fc->tab.cus, 0, sizeof(*fc->tab.cus) * ctu_count); @@ -386,7 +384,7 @@ static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc) av_refstruct_pool_uninit(&fc->rpl_tab_pool); fc->rpl_tab_pool = av_refstruct_pool_alloc(ctu_count * sizeof(RefPicListTab), 0); if (!fc->rpl_tab_pool) - return AVERROR(ENOMEM); + goto fail; } if (fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu) { @@ -394,7 +392,7 @@ static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc) fc->tab_dmvr_mvf_pool = av_refstruct_pool_alloc( pic_size_in_min_pu * sizeof(MvField), AV_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME); if (!fc->tab_dmvr_mvf_pool) - return AVERROR(ENOMEM); + goto fail; } fc->tab.sz.ctu_count = pps->ctb_count; @@ -410,6 +408,11 @@ static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc) fc->tab.sz.pixel_shift = sps->pixel_shift; return 0; + +fail: + fc->tab.sz.ctu_count = 0; + pic_arrays_free(fc); + return AVERROR(ENOMEM); } int ff_vvc_per_frame_init(VVCFrameContext *fc) -- 2.52.0 >From 00c2e3bea4756b04917bf10f22317a19ca33c808 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 7 Sep 2026 04:59:11 +0200 Subject: [PATCH 2/3] avcodec/vvc/dec: compare the CTU area in ibc_tl_init() Fixes: reallocation of the IBC virtual buffers on every frame --- libavcodec/vvc/dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c index d306fb0bf1..f7c51f01a1 100644 --- a/libavcodec/vvc/dec.c +++ b/libavcodec/vvc/dec.c @@ -301,7 +301,7 @@ static void ibc_tl_init(TabList *l, VVCFrameContext *fc) const int has_ibc = sps ? sps->r->sps_ibc_enabled_flag : 0; const int changed = fc->tab.sz.chroma_format_idc != chroma_idc || fc->tab.sz.ctu_height != ctu_height || - fc->tab.sz.ctu_size != ctu_size || + fc->tab.sz.ctu_size != ctu_size * ctu_size || fc->tab.sz.pixel_shift != ps; fc->tab.sz.ibc_buffer_width = ctu_size ? 2 * MAX_CTU_SIZE * MAX_CTU_SIZE / ctu_size : 0; -- 2.52.0 >From e0d38a803f1577f0320ebef924e065fd91409c0f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 7 Sep 2026 04:59:11 +0200 Subject: [PATCH 3/3] avcodec/vvc/thread: clear fc->ft when the frame thread is freed Fixes: use after free / double free --- libavcodec/vvc/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vvc/thread.c b/libavcodec/vvc/thread.c index 164ad83430..f898373bb9 100644 --- a/libavcodec/vvc/thread.c +++ b/libavcodec/vvc/thread.c @@ -711,7 +711,7 @@ void ff_vvc_frame_thread_free(VVCFrameContext *fc) ff_cond_destroy(&ft->cond); av_freep(&ft->rows); av_freep(&ft->tasks); - av_freep(&ft); + av_freep(&fc->ft); } static void frame_thread_init_score(VVCFrameContext *fc) -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
