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

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new c79dfd29e6 avcodec/h264_slice: guard color_frame() against 
chroma-width underflow
c79dfd29e6 is described below

commit c79dfd29e6afca56294395be843d98d10858a7fa
Author:     Franciszek Kalinowski <[email protected]>
AuthorDate: Tue May 19 09:36:50 2026 +0200
Commit:     michaelni <[email protected]>
CommitDate: Mon May 25 13:16:03 2026 +0000

    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.
---
 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 dbf7f60230..e3b4436fcb 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