PR #25700 opened by kierank
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25700
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25700.patch

With tile slice threading the slice covers every tile, but a corrupt
substream can signal the end of the slice segment inside a tile. The
tile then returned its CTB count as if it had finished, and
hls_slice_data_tiles went on to compute tile boundary strengths and run
the in-loop filters over CTBs that nothing had decoded, reading stale
motion data from an earlier frame. In an I slice cur_frame->refPicList
is NULL there, so boundary_strength() dereferenced a NULL pointer.

Found by fuzzing conformance streams with byte corruption, e.g. ENTP_B_LG_2
at -threads 8 -thread_type slice.

Found and written with AI


>From 80dd5799309f767806685bb672557eac09fdade4 Mon Sep 17 00:00:00 2001
From: Kieran Kunhya <[email protected]>
Date: Tue, 3 Nov 2026 01:49:37 +0100
Subject: [PATCH] avcodec/hevc/hevcdec: fail a tile that ends before its last
 CTB

With tile slice threading the slice covers every tile, but a corrupt
substream can signal the end of the slice segment inside a tile. The
tile then returned its CTB count as if it had finished, and
hls_slice_data_tiles went on to compute tile boundary strengths and run
the in-loop filters over CTBs that nothing had decoded, reading stale
motion data from an earlier frame. In an I slice cur_frame->refPicList
is NULL there, so boundary_strength() dereferenced a NULL pointer.

Found by fuzzing conformance streams with byte corruption, e.g. ENTP_B_LG_2
at -threads 8 -thread_type slice.
---
 libavcodec/hevc/hevcdec.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index f1bd5622913..7f02f69b362 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -3120,6 +3120,13 @@ static int hls_decode_entry_tile(AVCodecContext *avctx, 
void *hevc_lclist,
             return more_data;
         ctb_addr_ts++;
     }
+
+    /* The slice covers every tile, so a tile that ends before its last CTB
+     * is corrupt and leaves CTBs that the tile boundary strengths and the
+     * filters would read undecoded. */
+    if (ctb_addr_ts < sps->ctb_size && pps->tile_id[ctb_addr_ts] == job)
+        return AVERROR_INVALIDDATA;
+
     return ctb_addr_ts;
 }
 
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to