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]

Reply via email to