This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/8.0
in repository ffmpeg.

commit d86d43a5e7fab4cdc6ef0686e54062107d802d77
Author:     Franciszek Kalinowski <[email protected]>
AuthorDate: Tue May 19 09:36:50 2026 +0200
Commit:     Michael Niedermayer <[email protected]>
CommitDate: Sun Jun 14 04:59:02 2026 +0200

    avcodec/h264_slice: guard color_frame() against chroma-width underflow
    
    In the >= 9 bit path, color_frame() does
    `av_memcpy_backptr(dst + 2, 2, bytes - 2)`. When the effective chroma width
    is 1 pixel (bytes == 1) the count becomes -1 and the underlying fill16()
    loop runs roughly 2^32 times, producing a heap overflow. The original count
    was also wrong in units (pixels rather than bytes); fix that at the same
    time so the 2-pixel case still fills both pixels.
    
    Confirmed via a standalone harness reproducing av_memcpy_backptr's fill16
    loop with cnt = -1; reaching the call from a crafted H.264 bitstream
    requires Hi10P plus a frame_num gap on a frame whose effective chroma width
    is 1 pixel, which is hard to express but is reachable via mid-stream SPS
    changes. Compiles cleanly; no regressions seen running existing crafted
    H.264 PoCs and trivial transcodes.
    
    Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz 
Smigielski.
    
    (cherry picked from commit c79dfd29e6afca56294395be843d98d10858a7fa)
    Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/h264_slice.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index ef57186b94..e4ffda2721 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -316,8 +316,10 @@ static void color_frame(AVFrame *frame, const int c[4])
         int bytes  = is_chroma ? AV_CEIL_RSHIFT(frame->width,  
desc->log2_chroma_w) : frame->width;
         int height = is_chroma ? AV_CEIL_RSHIFT(frame->height, 
desc->log2_chroma_h) : frame->height;
         if (desc->comp[0].depth >= 9) {
-            ((uint16_t*)dst)[0] = c[p];
-            av_memcpy_backptr(dst + 2, 2, bytes - 2);
+            if (bytes >= 1)
+                ((uint16_t*)dst)[0] = c[p];
+            if (bytes >= 2)
+                av_memcpy_backptr(dst + 2, 2, 2 * (bytes - 1));
             dst += frame->linesize[p];
             for (int y = 1; y < height; y++) {
                 memcpy(dst, frame->data[p], 2*bytes);

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

Reply via email to