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

ispe width/height are read as uint32 but stored in int HEIFItem fields;
values above INT_MAX became negative, and read_image_grid() summing such
widths into coded_width overflowed int:
libavformat/mov.c:10404:33: runtime error: signed integer overflow: -2147483647 
+ -2147483647 cannot be represented in type 'int'

Also accumulate the grid tile dimensions and running offsets in 64bit
and validate the totals, as up to 256 tile columns of individually
valid widths can still overflow int.

Found-by: 51511
Signed-off-by: Michael Niedermayer <[email protected]>



>From 059eb2e853c1f62b8df1b73be9318061a7a21b0b Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Thu, 11 Jun 2026 16:34:26 +0200
Subject: [PATCH] avformat/mov: reject out of range ispe dimensions, avoid
 overflow summing HEIF tile dimensions

ispe width/height are read as uint32 but stored in int HEIFItem fields;
values above INT_MAX became negative, and read_image_grid() summing such
widths into coded_width overflowed int:
libavformat/mov.c:10404:33: runtime error: signed integer overflow: -2147483647 
+ -2147483647 cannot be represented in type 'int'

Also accumulate the grid tile dimensions and running offsets in 64bit
and validate the totals, as up to 256 tile columns of individually
valid widths can still overflow int.

Found-by: 51511
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavformat/mov.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 997a92dc0b..ee7b4f4d43 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -9521,6 +9521,12 @@ static int mov_read_ispe(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %"PRIu32", height 
%"PRIu32"\n",
            c->cur_item_id, width, height);
 
+    if (!width || !height || width > INT_MAX || height > INT_MAX) {
+        av_log(c->fc, AV_LOG_ERROR, "Invalid ispe dimensions 
%"PRIu32"x%"PRIu32"\n",
+               width, height);
+        return AVERROR_INVALIDDATA;
+    }
+
     item = get_heif_item(c, c->cur_item_id);
     if (item) {
         item->width  = width;
@@ -10524,8 +10530,10 @@ static int read_image_grid(AVFormatContext *s, const 
HEIFGrid *grid,
 {
     MOVContext *c = s->priv_data;
     const HEIFItem *item = grid->item;
+    int64_t coded_width = 0, coded_height = 0;
     int64_t offset = 0, pos = avio_tell(s->pb);
-    int x = 0, y = 0, i = 0;
+    int64_t x = 0, y = 0;
+    int i = 0;
     int tile_rows, tile_cols;
     int flags, size;
 
@@ -10567,9 +10575,15 @@ static int read_image_grid(AVFormatContext *s, const 
HEIFGrid *grid,
         return AVERROR_INVALIDDATA;
 
     for (int i = 0; i < tile_cols; i++)
-        tile_grid->coded_width  += grid->tile_item_list[i]->width;
+        coded_width  += grid->tile_item_list[i]->width;
     for (int i = 0; i < size; i += tile_cols)
-        tile_grid->coded_height += grid->tile_item_list[i]->height;
+        coded_height += grid->tile_item_list[i]->height;
+
+    if (coded_width > INT_MAX || coded_height > INT_MAX)
+        return AVERROR_INVALIDDATA;
+
+    tile_grid->coded_width  = coded_width;
+    tile_grid->coded_height = coded_height;
 
     tile_grid->offsets = av_calloc(tile_grid->nb_tiles, 
sizeof(*tile_grid->offsets));
     if (!tile_grid->offsets)
-- 
2.52.0

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

Reply via email to