PR #21601 opened by Kacper Michajłow (kasper93)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21601
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21601.patch


From cc99f1a3d1db2b1823c65ac9b941994356c7e456 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Wed, 28 Jan 2026 13:20:31 +0100
Subject: [PATCH 1/2] tools/target_sws_fuzzer: don't zero init dest buffer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Destination is destination and should be initialized by the sws itself.

Signed-off-by: Kacper Michajłow <[email protected]>
---
 tools/target_sws_fuzzer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/target_sws_fuzzer.c b/tools/target_sws_fuzzer.c
index 0e14adb1be..2aca0f3254 100644
--- a/tools/target_sws_fuzzer.c
+++ b/tools/target_sws_fuzzer.c
@@ -40,7 +40,7 @@ static void error(const char *err)
     exit(1);
 }
 
-static int alloc_plane(uint8_t *data[AV_VIDEO_MAX_PLANES], int 
stride[AV_VIDEO_MAX_PLANES], int w, int h, int format, int *hshift, int *vshift)
+static int alloc_plane(uint8_t *data[AV_VIDEO_MAX_PLANES], int 
stride[AV_VIDEO_MAX_PLANES], int w, int h, int format, int *hshift, int 
*vshift, int zero_init)
 {
     size_t size[AV_VIDEO_MAX_PLANES];
     ptrdiff_t ptrdiff_stride[AV_VIDEO_MAX_PLANES];
@@ -62,7 +62,7 @@ static int alloc_plane(uint8_t *data[AV_VIDEO_MAX_PLANES], 
int stride[AV_VIDEO_M
 
     for(int p=0; p<AV_VIDEO_MAX_PLANES; p++) {
         if (size[p]) {
-            data[p] = av_mallocz(size[p] + 32);
+            data[p] = zero_init ? av_mallocz(size[p] + 32) : av_malloc(size[p] 
+ 32);
             if (!data[p])
                 return -1;
         } else
@@ -153,11 +153,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t 
size) {
 
     // fprintf(stderr, "%d x %d %s -> %d x %d %s\n", srcW, srcH, 
desc_src->name, dstW, dstH, desc_dst->name);
 
-    ret = alloc_plane(src, srcStride, srcW, srcH, srcFormat, &srcHShift, 
&srcVShift);
+    ret = alloc_plane(src, srcStride, srcW, srcH, srcFormat, &srcHShift, 
&srcVShift, 1);
     if (ret < 0)
         goto end;
 
-    ret = alloc_plane(dst, dstStride, dstW, dstH, dstFormat, &dstHShift, 
&dstVShift);
+    ret = alloc_plane(dst, dstStride, dstW, dstH, dstFormat, &dstHShift, 
&dstVShift, 0);
     if (ret < 0)
         goto end;
 
-- 
2.52.0


From 329f6b8f01582390896abac55eacf21758256fc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Wed, 28 Jan 2026 13:22:50 +0100
Subject: [PATCH 2/2] tools/target_sws_fuzzer: add sws filters to fuzzing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Recent regression in commit 795bb37a39e163cbb5b6d897ebb0ca90ea7b449a
that skipped clearing some internal buffers, caused pretty significant
security implications:
478212631/clusterfuzz-testcase-minimized-fuzzer_set_property_MPV_FORMAT_STRING_1-5143269947539456
478212631/clusterfuzz-testcase-minimized-fuzzer_set_property_MPV_FORMAT_STRING_1-5389230846312448
478212631/clusterfuzz-testcase-minimized-fuzzer_set_property_MPV_FORMAT_STRING_1-4732512093143040
478212631/clusterfuzz-testcase-minimized-fuzzer_set_property_MPV_FORMAT_STRING_1-4791771971518464
478212631/clusterfuzz-testcase-minimized-fuzzer_set_property_MPV_FORMAT_STRING_1-6030282833854464
478301104/clusterfuzz-testcase-minimized-fuzzer_set_property_MPV_FORMAT_STRING_1-5053287094353920

Found-by: https://github.com/google/oss-fuzz/tree/master/projects/mpv

None of which were found by FFmpeg's fuzzing infrastructure, so update
the SWS fuzzer to account for that.

Signed-off-by: Kacper Michajłow <[email protected]>
---
 tools/target_sws_fuzzer.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/tools/target_sws_fuzzer.c b/tools/target_sws_fuzzer.c
index 2aca0f3254..4a0b639526 100644
--- a/tools/target_sws_fuzzer.c
+++ b/tools/target_sws_fuzzer.c
@@ -102,6 +102,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t 
size) {
     uint8_t *dst[AV_VIDEO_MAX_PLANES] = { 0 };
     struct SwsContext *sws = NULL;
     const AVPixFmtDescriptor *desc_src, *desc_dst;
+    SwsFilter *src_filter = NULL;
+    SwsFilter *dst_filter = NULL;
+    int use_filter = 0;
+    float filter_luma_gblur = 0, filter_chroma_gblur = 0;
+    float filter_luma_sharpen = 0, filter_chroma_sharpen = 0;
+    float filter_chroma_hshift = 0, filter_chroma_vshift = 0;
 
     if (size > 128) {
         GetByteContext gbc;
@@ -141,6 +147,24 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t 
size) {
         if (flags64 & 0x10)
             av_force_cpu_flags(0);
 
+        use_filter = flags64 & 0x20;
+        if (use_filter) {
+            const uint32_t param_max = 0xFF;
+            uint32_t luma_gblur = bytestream2_get_le32(&gbc) % param_max;
+            uint32_t chroma_gblur = bytestream2_get_le32(&gbc) % param_max;
+            uint32_t luma_sharpen = bytestream2_get_le32(&gbc) % param_max;
+            uint32_t chroma_sharpen = bytestream2_get_le32(&gbc) % param_max;
+            uint32_t chroma_hshift = bytestream2_get_le32(&gbc) % param_max;
+            uint32_t chroma_vshift = bytestream2_get_le32(&gbc) % param_max;
+
+            filter_luma_gblur = (float)luma_gblur / param_max * 200.0f - 
100.0f;
+            filter_chroma_gblur = (float)chroma_gblur / param_max * 200.0f - 
100.0f;
+            filter_luma_sharpen = (float)luma_sharpen / param_max * 200.0f - 
100.0f;
+            filter_chroma_sharpen = (float)chroma_sharpen / param_max * 200.0f 
- 100.0f;
+            filter_chroma_hshift = (float)chroma_hshift / param_max * 200.0f - 
100.0f;
+            filter_chroma_vshift = (float)chroma_vshift / param_max * 200.0f - 
100.0f;
+        }
+
         if (av_image_check_size(srcW, srcH, srcFormat, NULL) < 0)
             srcW = srcH = 23;
         if (av_image_check_size(dstW, dstH, dstFormat, NULL) < 0)
@@ -186,7 +210,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t 
size) {
     av_opt_set_int(sws, "dst_format", dstFormat, 0);
     av_opt_set(sws, "alphablend", "none", 0);
 
-    ret = sws_init_context(sws, NULL, NULL);
+    if (use_filter) {
+        src_filter = sws_getDefaultFilter(filter_luma_gblur, 
filter_chroma_gblur,
+                                          filter_luma_sharpen, 
filter_chroma_sharpen,
+                                          filter_chroma_hshift, 
filter_chroma_vshift, 0);
+        dst_filter = sws_getDefaultFilter(filter_luma_gblur, 
filter_chroma_gblur,
+                                          filter_luma_sharpen, 
filter_chroma_sharpen,
+                                          filter_chroma_hshift, 
filter_chroma_vshift, 0);
+    }
+
+    ret = sws_init_context(sws, src_filter, dst_filter);
     if (ret < 0)
         goto end;
 
@@ -194,6 +227,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t 
size) {
     sws_scale(sws, (const uint8_t * const*)src, srcStride, 0, srcH, dst, 
dstStride);
 
 end:
+    sws_freeFilter(dst_filter);
+    sws_freeFilter(src_filter);
     sws_freeContext(sws);
 
     free_plane(src);
-- 
2.52.0

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

Reply via email to