>From 1d4cc49831864d703080e507ea1761dc0547786c Mon Sep 17 00:00:00 2001 From: OxBat Date: Sat, 3 Jan 2026 19:24:01 +0100 Subject: [PATCH] avcodec/vvc: harden memory accesses in CTU (heap overflow, OOB read) --- libavcodec/vvc/ctu.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/libavcodec/vvc/ctu.c b/libavcodec/vvc/ctu.c index 18cbe0fe0f..bf7cc074be 100644 --- a/libavcodec/vvc/ctu.c +++ b/libavcodec/vvc/ctu.c @@ -52,6 +52,11 @@ static void set_tb_size(const VVCFrameContext *fc, const TransformBlock *tb) for (int y = y_tb; y < end; y++) { const int off = y * fc->ps.pps->min_tu_width + x_tb; +/* PATCH: Check bounds to prevent heap overflow */ + int max_off = fc->ps.pps->min_tu_width * fc->ps.pps->min_tu_height; + if (off + width > max_off) { + return; + } memset(fc->tab.tb_width [is_chroma] + off, tb->tb_width, width); memset(fc->tab.tb_height[is_chroma] + off, tb->tb_height, width); } @@ -1185,6 +1190,8 @@ static void set_cb_pos(const VVCFrameContext *fc, const CodingUnit *cu) fc->tab.cb_pos_x[ch_type][x + i] = cu->x0; fc->tab.cb_pos_y[ch_type][x + i] = cu->y0; } + /* PATCH: Prevent heap overflow */ + if (x + width > fc->ps.pps->min_tu_width * fc->ps.pps->min_tu_height) return; memset(&fc->tab.cb_width[ch_type][x], cu->cb_width, width); memset(&fc->tab.cb_height[ch_type][x], cu->cb_height, width); memset(&fc->tab.cqt_depth[ch_type][x], cu->cqt_depth, width); @@ -1287,10 +1294,15 @@ static void derive_mmvd(const VVCLocalContext *lc, MvField *mvf, const Mv *mmvd_ if (mvf->pred_flag == PF_BI) { const RefPicList *rpl = sc->rpl; const int poc = lc->fc->ps.ph.poc; - const int diff[] = { - poc - rpl[L0].refs[mvf->ref_idx[L0]].poc, - poc - rpl[L1].refs[mvf->ref_idx[L1]].poc - }; +/* PATCH: Validate reference indices */ + if (mvf->ref_idx[L0] >= rpl[L0].nb_refs || + mvf->ref_idx[L1] >= rpl[L1].nb_refs) + return; + + const int diff[] = { + poc - rpl[L0].refs[mvf->ref_idx[L0]].poc, + poc - rpl[L1].refs[mvf->ref_idx[L1]].poc + }; const int sign = FFSIGN(diff[0]) != FFSIGN(diff[1]); if (diff[0] == diff[1]) { @@ -1932,7 +1944,11 @@ static void palette_update_predictor(VVCLocalContext *lc, const bool local_dual_ } } - memcpy(pp->entries, plt->entries, i * sizeof(pp->entries[0])); +/* PATCH: Clamp size to avoid overflow */ +if (i > VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE) + i = VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE; + +memcpy(pp->entries, plt->entries, i * sizeof(pp->entries[0])); pp->size = i; } } -- 2.52.0.windows.1