PR #22786 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22786
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22786.patch

These align the filter size to a multiple of the internal tap grouping
(either 1/2/4 for vpgatherdd, or the XMM size for the 4x4 transposed kernel).
This may over-read past the natural end of the input buffer, if the aligned
size exceeds the true size.

Signed-off-by: Niklas Haas <[email protected]>


>From d5921fe42217ccb60a7ff7ebe1887223e727b319 Mon Sep 17 00:00:00 2001
From: Niklas Haas <[email protected]>
Date: Sat, 11 Apr 2026 02:40:58 +0200
Subject: [PATCH] swscale/x86/ops: set missing over_read metadata on filter ops

These align the filter size to a multiple of the internal tap grouping
(either 1/2/4 for vpgatherdd, or the XMM size for the 4x4 transposed kernel).
This may over-read past the natural end of the input buffer, if the aligned
size exceeds the true size.

Signed-off-by: Niklas Haas <[email protected]>
---
 libswscale/x86/ops.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c
index ab113aa780..88c9fed919 100644
--- a/libswscale/x86/ops.c
+++ b/libswscale/x86/ops.c
@@ -349,7 +349,8 @@ static int setup_filter_h(const SwsImplParams *params, 
SwsImplResult *out)
      * size, we need to gather 2/4 taps simultaneously and unroll the inner
      * loop over several packed samples.
      */
-    const int taps_align = sizeof(int32_t) / ff_sws_pixel_type_size(op->type);
+    const int pixel_size = ff_sws_pixel_type_size(op->type);
+    const int taps_align = sizeof(int32_t) / pixel_size;
     const int filter_size = filter->filter_size;
     const int block_size = params->table->block_size;
     const size_t aligned_size = FFALIGN(filter_size, taps_align);
@@ -418,6 +419,7 @@ static int setup_filter_h(const SwsImplParams *params, 
SwsImplResult *out)
     out->priv.ptr = weights.ptr;
     out->priv.uptr[1] = aligned_size;
     out->free = ff_op_priv_free;
+    out->over_read = (aligned_size - filter_size) * pixel_size;
     return 0;
 }
 
@@ -449,6 +451,7 @@ static int setup_filter_4x4_h(const SwsImplParams *params, 
SwsImplResult *out)
 {
     const SwsOp *op = params->op;
     const SwsFilterWeights *filter = op->rw.kernel;
+    const int pixel_size = ff_sws_pixel_type_size(op->type);
     const int sizeof_weights = hscale_sizeof_weight(op);
     const int block_size = params->table->block_size;
     const int taps_align = 16 / sizeof_weights; /* taps per iteration (XMM) */
@@ -499,6 +502,7 @@ static int setup_filter_4x4_h(const SwsImplParams *params, 
SwsImplResult *out)
     out->priv.ptr = weights.ptr;
     out->priv.uptr[1] = aligned_size * sizeof_weights;
     out->free = ff_op_priv_free;
+    out->over_read = (aligned_size - filter_size) * pixel_size;
     return 0;
 }
 
-- 
2.52.0

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

Reply via email to