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

Fix two buffer overreads in the PowerPC yuv2planeX SIMD paths that cause daily 
FATE `checkasm-sw_scale` ASAN failures on both ppc64 (G5, altivec) and ppc64le 
(POWER9, VSX):

**1. VSX LOAD_FILTER overread** (`swscale_vsx.c`)

`vec_vsx_ld(joffset, filter)` reads 16 bytes at the given byte offset. When 
`joffset >= filterSize*2 - 14` (e.g. `joffset=30` for `filterSize=16`), this 
reads up to 14 bytes past the 32-byte filter array. Fix: replace with 
`vec_splats(f[j])` which only reads the single `int16_t` element needed (the 
result is splatted to all lanes anyway).

**2. GET_LS look-ahead overread** (`swscale_ppc_template.c`)

`yuv2planeX_8_16` calls `yuv2planeX_8` twice per filter tap. Each call's 
`GET_LS` macro speculatively loads the next 16-byte vector for pipelining. On 
the second call, this look-ahead reads 16 bytes past the last valid source 
element. Fix: tighten the SIMD loop bound from `(dstW - 15)` to `(dstW - 23)`, 
ensuring the farthest speculative load stays within `src[j][0..dstW-1]`. The 
scalar fallback handles the remaining 16-23 trailing pixels.

**FATE ASAN reports:**
```
ppc64 (altivec): stack-buffer-overflow in yuv2planeX_8_16_altivec at 
swscale_ppc_template.c:56
ppc64le (VSX):   unknown-crash in yuv2planeX_8_16_vsx at 
swscale_ppc_template.c:52
```

Signed-off-by: Scott Boudreaux <[email protected]>


>From 06c62bf08502e6068c70cb51d71432260344b1e4 Mon Sep 17 00:00:00 2001
From: Scott Boudreaux <[email protected]>
Date: Wed, 18 Mar 2026 18:28:09 +0000
Subject: [PATCH 1/2] swscale/ppc: fix ASAN stack-buffer-overflow in yuv2planeX

Fix two buffer overreads in the PowerPC yuv2planeX SIMD paths
that cause daily FATE checkasm-sw_scale ASAN failures on both
ppc64 (G5, altivec) and ppc64le (POWER9, VSX):

1. VSX LOAD_FILTER: vec_vsx_ld(joffset, filter) reads 16 bytes
   at the given byte offset.  When joffset >= filterSize*2 - 14
   (e.g. joffset=30 for filterSize=16), this reads up to 14 bytes
   past the 32-byte filter array.  Fix by replacing the vector
   load with vec_splats(f[j]) which only reads the single int16_t
   element needed (the result is splatted to all lanes anyway).

2. GET_LS look-ahead overread: yuv2planeX_8_16 calls
   yuv2planeX_8 twice per filter tap.  Each call's GET_LS macro
   speculatively loads the next 16-byte vector for pipelining.
   On the second call, this look-ahead reads 16 bytes past the
   last valid source element.  Fix by tightening the SIMD loop
   bound from (dstW - 15) to (dstW - 23), ensuring the farthest
   speculative load stays within src[j][0..dstW-1].  The scalar
   fallback handles the remaining 16-23 trailing pixels.

The ASAN reports from FATE:
  ppc64 (altivec): stack-buffer-overflow in yuv2planeX_8_16_altivec
                   at swscale_ppc_template.c:56
  ppc64le (VSX):   unknown-crash in yuv2planeX_8_16_vsx
                   at swscale_ppc_template.c:52

Signed-off-by: Scott Boudreaux <[email protected]>
---
 libswscale/ppc/swscale_ppc_template.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libswscale/ppc/swscale_ppc_template.c 
b/libswscale/ppc/swscale_ppc_template.c
index 1e0c095285..f352f75fa9 100644
--- a/libswscale/ppc/swscale_ppc_template.c
+++ b/libswscale/ppc/swscale_ppc_template.c
@@ -90,7 +90,7 @@ static void FUNC(yuv2planeX)(const int16_t *filter, int 
filterSize,
 
     yuv2planeX_u(filter, filterSize, src, dest, dst_u, dither, offset, 0);
 
-    for (i = dst_u; i < dstW - 15; i += 16)
+    for (i = dst_u; i < dstW - 23; i += 16)
         FUNC(yuv2planeX_8_16)(filter, filterSize, src, dest + i, dither,
                               offset, i);
 
-- 
2.52.0


>From d2a8f3cd7f0af6b03375438553974332face1469 Mon Sep 17 00:00:00 2001
From: Scott Boudreaux <[email protected]>
Date: Wed, 18 Mar 2026 18:28:22 +0000
Subject: [PATCH 2/2] swscale/ppc: fix LOAD_FILTER overread in VSX path

Part of the yuv2planeX ASAN fix - replace vec_vsx_ld with vec_splats
to avoid reading past the filter array.

Signed-off-by: Scott Boudreaux <[email protected]>
---
 libswscale/ppc/swscale_vsx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c
index c6948546d5..21fb43092d 100644
--- a/libswscale/ppc/swscale_vsx.c
+++ b/libswscale/ppc/swscale_vsx.c
@@ -54,7 +54,7 @@
     } while (0)
 
 #define LOAD_FILTER(vf,f) {\
-        vf = vec_vsx_ld(joffset, f);\
+        vf = vec_splats(f[j]);\
 }
 #define LOAD_L1(ll1,s,p){\
         ll1  = vec_vsx_ld(xoffset, s);\
-- 
2.52.0

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

Reply via email to