[PR] libswscale/ppc/yuv2rgb_altivec: Fix heap buffer overflow in yuv2packedX (PR #24204)

haochenc via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <[email protected]>
PR #24204 opened by haochenc
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24204
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24204.patch

Signed-off-by: Hao Chen <[email protected]>

# Summary of changes

Fixes a heap buffer overflow in AltiVec's `yuv2packedX_altivec` implementation within `libswscale`. 

The core issues were twofold:
1. **Loop boundary and tail handling logic:** The AltiVec SIMD loop processed 16 pixels at a time. The loop condition `i < dstW` could lead to buffer overflows at the end of the destination buffer if `dstW` was not a multiple of 16. By changing the loop condition to `i < dstW - 15`, it ensures the main loop only processes full 16-pixel blocks, leaving the tail exactly for the fallback path.
2. **Incorrect `memcpy` byte-count for trailing pixels:** The fallback copy logic was computing the memcpy length as `(dstW - i) / 4` which miscalculated the size array slices, especially breaking for 24-bit formats. This PR corrects the copy logic to use `(dstW - i) * pixel_stride` factoring in the exact stride required (e.g. 3 bytes for RGB24/BGR24 and 4 bytes for 32-bit formats) to accurately write out the remaining tail pixels.


>From 2d7c223e890554e616dcbb902480cc7dafa07906 Mon Sep 17 00:00:00 2001
From: Hao Chen <[email protected]>
Date: Tue, 18 Aug 2026 00:26:47 +0000
Subject: [PATCH] libswscale/ppc/yuv2rgb_altivec: Fix heap buffer overflow in
 yuv2packedX

Signed-off-by: Hao Chen <[email protected]>
---
 libswscale/ppc/yuv2rgb_altivec.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index cad3f8d7c0..8eac5e4494 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -705,7 +705,7 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c,
 
     out = (vector unsigned char *) dest;
 
-    for (i = 0; i < dstW; i += 16) {
+    for (i = 0; i < dstW - 15; i += 16) {
         Y0 = RND;
         Y1 = RND;
         /* extract 16 coeffs from lumSrc */
@@ -795,8 +795,6 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c,
     }
 
     if (i < dstW) {
-        i -= 16;
-
         Y0 = RND;
         Y1 = RND;
         /* extract 16 coeffs from lumSrc */
@@ -878,7 +876,8 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c,
             return;
         }
 
-        memcpy(&((uint32_t *) dest)[i], scratch, (dstW - i) / 4);
+        int pixel_stride = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
+        memcpy(&dest[i * pixel_stride], scratch, (dstW - i) * pixel_stride);
     }
 }
 
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.