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

Fixes: SEGV write in ff_yuyvtoyuv420_neon()
Fixes: sws-neon-yuyv422-segv-preexisting (fairy/pr21601-repro)
Fixes: heap-buffer-overflow read in hScale8To15_c()
Fixes: sws-filter-oob-handcrafted / gen3.py (fairy/pr21601-repro)
Found-by: Forgejo Fairy while reviewing PR #21601


>From f67c03fd28be52c382f29b5fadefc9158d527bd9 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 9 Sep 2026 04:08:30 +0200
Subject: [PATCH 1/4] cosmetics: checkasm/sw_rgb: move cmp_off_by_n() above
 check_interleaved_to_planar()

---
 tests/checkasm/sw_rgb.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c
index 7bf5d8e175..bbad945a62 100644
--- a/tests/checkasm/sw_rgb.c
+++ b/tests/checkasm/sw_rgb.c
@@ -72,6 +72,15 @@ static void check_shuffle_bytes(void * func, const char * 
report)
     }
 }
 
+static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int 
accuracy)
+{
+    for (size_t i = 0; i < n; i++) {
+        if (abs(ref[i] - test[i]) > accuracy)
+            return 1;
+    }
+    return 0;
+}
+
 static void check_interleaved_to_planar(void *func, const char *report, int 
odd_tail)
 {
     int i;
@@ -122,15 +131,6 @@ static void check_interleaved_to_planar(void *func, const 
char *report, int odd_
 #define MAX_LINE_SIZE 1920
 #define BUFSIZE (NUM_LINES * MAX_LINE_SIZE)
 
-static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int 
accuracy)
-{
-    for (size_t i = 0; i < n; i++) {
-        if (abs(ref[i] - test[i]) > accuracy)
-            return 1;
-    }
-    return 0;
-}
-
 static void check_rgb24toyv12(SwsContext *sws)
 {
     static const int input_sizes[] = {16, 128, 512, MAX_LINE_SIZE, 
-MAX_LINE_SIZE};
-- 
2.52.0


>From c88bbaced5d39571840343994ab3d957b2e45f13 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 9 Sep 2026 04:10:43 +0200
Subject: [PATCH 2/4] swscale/utils: do not let a filter wider than the source
 read past the line

Fixes: heap-buffer-overflow read in hScale8To15_c()
Fixes: sws-filter-oob-handcrafted / gen3.py (fairy/pr21601-repro)
Found-by: Forgejo Fairy while reviewing PR #21601
---
 libswscale/utils.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libswscale/utils.c b/libswscale/utils.c
index 59b6776f6a..9d0353cb80 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -494,7 +494,6 @@ static av_cold int initFilter(int16_t **outFilter, int32_t 
**filterPos,
         ret = RETCODE_USE_CASCADE;
         goto fail;
     }
-    *outFilterSize = filterSize;
 
     if (flags & SWS_PRINT_INFO)
         av_log(NULL, AV_LOG_VERBOSE,
@@ -559,6 +558,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t 
**filterPos,
         }
     }
 
+    *outFilterSize = FFMIN(filterSize, FFALIGN(srcW, filterAlign));
+
     // Note the +1 is for the MMX scaler which reads over the end
     /* align at 16 for AltiVec (needed by hScale_altivec_real) */
     *outFilter = av_calloc(dstW + 3, *outFilterSize * sizeof(**outFilter));
-- 
2.52.0


>From c25318fc68b887a0b55f2bbf312ac05fc0d8a6bb Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 9 Sep 2026 04:10:43 +0200
Subject: [PATCH 3/4] swscale/aarch64: fix uyvy/yuyv to yuv420p on height 1

Fixes: SEGV write in ff_yuyvtoyuv420_neon()
Fixes: sws-neon-yuyv422-segv-preexisting (fairy/pr21601-repro)
Found-by: Forgejo Fairy while reviewing PR #21601
---
 libswscale/aarch64/rgb2rgb_neon.S | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/libswscale/aarch64/rgb2rgb_neon.S 
b/libswscale/aarch64/rgb2rgb_neon.S
index ba2f904879..1c14100fbb 100644
--- a/libswscale/aarch64/rgb2rgb_neon.S
+++ b/libswscale/aarch64/rgb2rgb_neon.S
@@ -884,6 +884,7 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1
 
         b.eq            6f
 
+        cbz             w5, 11f
 1:                                                        // fast path - the 
width is at least 32
         and             w14, w4, #~31                     // w14 is the main 
loop counter
         and             w9, w4, #31                       // w9 holds the 
remaining width, 0 to 31
@@ -896,7 +897,7 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1
         subs            w5, w5, #1
         move_pointers_to_next_line \src_fmt, \dst_fmt
         b.ne            1b
-
+11:
 .ifc \dst_fmt, yuv420                                    // handle the last 
line in case the height is odd
         cbz             w17, 3f
         and             w14, w4, #~31
@@ -915,6 +916,8 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1
         ret
 
 6:                                                        // slow path - width 
is at most 31
+        cbz             w5, 12f
+13:
         and             w9, w4, #31
         cbz             w9, 9f                            // even part empty 
(orig width 0 or 1)
 7:
@@ -925,8 +928,8 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1
         write_last_odd_column \src_fmt, \dst_fmt
         subs            w5, w5, #1
         move_pointers_to_next_line \src_fmt, \dst_fmt
-        b.ne            6b
-
+        b.ne            13b
+12:
 .ifc \dst_fmt, yuv420
         cbz             w17, 8f
         and             w9, w4, #31
-- 
2.52.0


>From 19a1683023cdf383ac965b38ed7d6068705a3b36 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 9 Sep 2026 04:10:43 +0200
Subject: [PATCH 4/4] checkasm/sw_rgb: also test uyvytoyuv420 and yuyvtoyuv420

---
 tests/checkasm/sw_rgb.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c
index bbad945a62..d29a897a54 100644
--- a/tests/checkasm/sw_rgb.c
+++ b/tests/checkasm/sw_rgb.c
@@ -81,7 +81,8 @@ static int cmp_off_by_n(const uint8_t *ref, const uint8_t 
*test, size_t n, int a
     return 0;
 }
 
-static void check_interleaved_to_planar(void *func, const char *report, int 
odd_tail)
+static void check_interleaved_to_planar(void *func, const char *report, int 
odd_tail,
+                                        int chroma_tolerance)
 {
     int i;
 
@@ -118,8 +119,8 @@ static void check_interleaved_to_planar(void *func, const 
char *report, int odd_
             call_new(dst_y_1, dst_u_1, dst_v_1, src1, w, h,
                      MAX_STRIDE, MAX_STRIDE / 2, srcStride);
             if (memcmp(dst_y_0, dst_y_1, MAX_STRIDE * MAX_HEIGHT) ||
-                memcmp(dst_u_0, dst_u_1, (MAX_STRIDE/2) * MAX_HEIGHT) ||
-                memcmp(dst_v_0, dst_v_1, (MAX_STRIDE/2) * MAX_HEIGHT))
+                cmp_off_by_n(dst_u_0, dst_u_1, (MAX_STRIDE/2) * MAX_HEIGHT, 
chroma_tolerance) ||
+                cmp_off_by_n(dst_v_0, dst_v_1, (MAX_STRIDE/2) * MAX_HEIGHT, 
chroma_tolerance))
                 fail();
         }
         bench_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[5].w, planes[5].h,
@@ -960,11 +961,16 @@ void checkasm_check_sw_rgb(void)
     }
     report("rgb24tobgr32");
 
-    check_interleaved_to_planar(uyvytoyuv422, "uyvytoyuv422", 1);
+    check_interleaved_to_planar(uyvytoyuv422, "uyvytoyuv422", 1, 0);
     report("uyvytoyuv422");
-    check_interleaved_to_planar(yuyvtoyuv422, "yuyvtoyuv422", 2);
+    check_interleaved_to_planar(yuyvtoyuv422, "yuyvtoyuv422", 2, 0);
     report("yuyvtoyuv422");
 
+    check_interleaved_to_planar(uyvytoyuv420, "uyvytoyuv420", 1, 1);
+    report("uyvytoyuv420");
+    check_interleaved_to_planar(yuyvtoyuv420, "yuyvtoyuv420", 2, 1);
+    report("yuyvtoyuv420");
+
     check_interleave_bytes();
     report("interleave_bytes");
 
-- 
2.52.0

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

Reply via email to