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

# Summary of changes

Internal calculation must sometimes be in 64-bit.
example with 12k8k16-bit content:
linesize = align(size.x*bits_per_comp*nb_comp, 32)
uint offs = pos.y*linesize + pos.x*nb_comp*bits_per_comp;
-->
linesize = 12000 \* 16 \* 3 = 576 000.
offs = 8 000 \* 576 000 + 0 = 4 608 000 000 ( so > 2^32)

Keeping 32-bit after the division by the bits per comp is currently relatively 
safe, 12k content is already rare, and we can go theoretically up to more than 
100k content with this patch (not realistic and FFmpeg would crash elsewhere 
before reaching this code).

cc @lynne


>From fb69a52303cb945e9adc2851c84c4de019b6ee6a Mon Sep 17 00:00:00 2001
From: Maxime Gervais <[email protected]>
Date: Thu, 17 Sep 2026 21:16:41 +0200
Subject: [PATCH] vulkan/dpx: Fix int overflow

Signed-off-by: Maxime Gervais <[email protected]>
---
 libavcodec/vulkan/dpx_copy.comp.glsl   | 6 ++++--
 libavcodec/vulkan/dpx_unpack.comp.glsl | 3 +--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vulkan/dpx_copy.comp.glsl 
b/libavcodec/vulkan/dpx_copy.comp.glsl
index 124caea494..e42b87c32d 100644
--- a/libavcodec/vulkan/dpx_copy.comp.glsl
+++ b/libavcodec/vulkan/dpx_copy.comp.glsl
@@ -76,8 +76,10 @@ void main(void)
     uint linesize;
     linesize = align(size.x*bits_per_comp*nb_comp, 32);
 
-    uint offs = pos.y*linesize + pos.x*nb_comp*bits_per_comp;
-    offs /= bits_per_comp;
+    /* The offset must be computed in 64 bits as pos.y*linesize can exceed
+       UINT32_MAX for large frames */
+    uint offs = uint((U64(pos.y)*linesize + pos.x*nb_comp*bits_per_comp)
+                     / bits_per_comp);
 
     if (nb_images == 1) {
         uvec4 val;
diff --git a/libavcodec/vulkan/dpx_unpack.comp.glsl 
b/libavcodec/vulkan/dpx_unpack.comp.glsl
index e169ac07aa..b4b754294e 100644
--- a/libavcodec/vulkan/dpx_unpack.comp.glsl
+++ b/libavcodec/vulkan/dpx_unpack.comp.glsl
@@ -68,10 +68,9 @@ i16vec4 parse_packed_in_32(ivec2 pos, int stride)
     line_size += line_size & 31;
     line_size += need_align << 3;
 
-    uint line_off = pos.y*line_size;
     uint pix_off = pos.x*bits_per_comp*nb_comp;
 
-    uint off = (line_off + pix_off) >> 5;
+    uint off = uint((U64(pos.y)*line_size + pix_off) >> 5);
     uint bit = pix_off & 0x1f;
 
     uint32_t d0 = read_data(off + 0);
-- 
2.52.0

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

Reply via email to