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

The function is the Vulkan-filter primitive for "N inputs", but the
implementation used fixed-size stack arrays sized for at most 16
inputs and 128 image barriers:

    VkImageView in_views[16][AV_NUM_DATA_POINTERS];
    VkImageMemoryBarrier2 img_bar[128];

with no bounds check on the caller-supplied nb_in. Any nb_in > 16
writes past the end of in_views, corrupting the calling stack frame.
The img_bar[128] limit is also exceeded earlier than the in_views
limit suggests, because ff_vk_frame_barrier() appends up to
AV_NUM_DATA_POINTERS entries per input frame: with planar Vulkan
frames already at nb_in == 16 the barrier count is
(nb_in + 1) * AV_NUM_DATA_POINTERS = 136, past the 128-slot stack
array.

Code is believed to be not exploitable with the current callers

Switch both arrays to nb_in-sized heap allocations so the function
actually lives up to its name, reject negative nb_in, and free in
both the success and failure paths.

Reported by k00shi_.


>From def3079960630d24d571099350dfafa86c8102f8 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 27 May 2026 00:44:06 +0200
Subject: [PATCH] avfilter/vulkan_filter: drop silent caps on
 ff_vk_filter_process_Nin

The function is the Vulkan-filter primitive for "N inputs", but the
implementation used fixed-size stack arrays sized for at most 16
inputs and 128 image barriers:

    VkImageView in_views[16][AV_NUM_DATA_POINTERS];
    VkImageMemoryBarrier2 img_bar[128];

with no bounds check on the caller-supplied nb_in. Any nb_in > 16
writes past the end of in_views, corrupting the calling stack frame.
The img_bar[128] limit is also exceeded earlier than the in_views
limit suggests, because ff_vk_frame_barrier() appends up to
AV_NUM_DATA_POINTERS entries per input frame: with planar Vulkan
frames already at nb_in == 16 the barrier count is
(nb_in + 1) * AV_NUM_DATA_POINTERS = 136, past the 128-slot stack
array.

Code is believed to be not exploitable with the current callers

Switch both arrays to nb_in-sized heap allocations so the function
actually lives up to its name, reject negative nb_in, and free in
both the success and failure paths.

Reported by k00shi_.
---
 libavfilter/vulkan_filter.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c
index 2fc467c6d9..0ed483ef96 100644
--- a/libavfilter/vulkan_filter.c
+++ b/libavfilter/vulkan_filter.c
@@ -20,6 +20,7 @@
 
 #include "filters.h"
 #include "vulkan_filter.h"
+#include "libavutil/mem.h"
 #include "libavutil/vulkan_loader.h"
 
 int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
@@ -414,14 +415,23 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, 
FFVkExecPool *e,
 {
     int err = 0;
     FFVulkanFunctions *vk = &vkctx->vkfn;
-    VkImageView in_views[16][AV_NUM_DATA_POINTERS];
+    VkImageView (*in_views)[AV_NUM_DATA_POINTERS] = NULL;
     VkImageView out_views[AV_NUM_DATA_POINTERS];
-    VkImageMemoryBarrier2 img_bar[128];
+    VkImageMemoryBarrier2 *img_bar = NULL;
     int nb_img_bar = 0;
     VkImageLayout in_layout = sampler != VK_NULL_HANDLE ?
                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
                               VK_IMAGE_LAYOUT_GENERAL;
 
+    if (nb_in < 0)
+        return AVERROR(EINVAL);
+    in_views = av_calloc(nb_in, sizeof(*in_views));
+    img_bar = av_calloc(nb_in + 1, AV_NUM_DATA_POINTERS * sizeof(*img_bar));
+    if (!in_views || !img_bar) {
+        err = AVERROR(ENOMEM);
+        goto end;
+    }
+
     /* Update descriptors and init the exec context */
     FFVkExecContext *exec = ff_vk_exec_get(vkctx, e);
     ff_vk_exec_start(vkctx, exec);
@@ -479,8 +489,12 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, 
FFVkExecPool *e,
                     FFALIGN(vkctx->output_height, 
shd->lg_size[1])/shd->lg_size[1],
                     wgc_z);
 
-    return ff_vk_exec_submit(vkctx, exec);
+    err = ff_vk_exec_submit(vkctx, exec);
+    goto end;
 fail:
     ff_vk_exec_discard_deps(vkctx, exec);
+end:
+    av_free(in_views);
+    av_free(img_bar);
     return err;
 }
-- 
2.52.0

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

Reply via email to