[PATCH] Fix tile_start_off calculations for extremely large frame sizes
authorHenrik Gramner <gramner@twoorioles.com>
Tue, 21 Nov 2023 19:47:50 +0000 (20:47 +0100)
committerMoritz Mühlenhoff <jmm@debian.org>
Thu, 25 Apr 2024 17:31:24 +0000 (19:31 +0200)
The tile start offset, in pixels, can exceed the range of a signed int.

Gbp-Pq: Name CVE-2024-1580.patch

src/decode.c
src/internal.h

index 13d57060710a25ab8da44274785700b6b1bdc926..eeb6e77bc08f465172c630fc6130fcbb8f4e1e61 100644 (file)
@@ -2618,7 +2618,7 @@ static void setup_tile(Dav1dTileState *const ts,
                        const Dav1dFrameContext *const f,
                        const uint8_t *const data, const size_t sz,
                        const int tile_row, const int tile_col,
-                       const int tile_start_off)
+                       const unsigned tile_start_off)
 {
     const int col_sb_start = f->frame_hdr->tiling.col_start_sb[tile_col];
     const int col_sb128_start = col_sb_start >> !f->seq_hdr->sb128;
@@ -2969,15 +2969,16 @@ int dav1d_decode_frame_init(Dav1dFrameContext *const f) {
     const uint8_t *const size_mul = ss_size_mul[f->cur.p.layout];
     const int hbd = !!f->seq_hdr->hbd;
     if (c->n_fc > 1) {
+        const unsigned sb_step4 = f->sb_step * 4;
         int tile_idx = 0;
         for (int tile_row = 0; tile_row < f->frame_hdr->tiling.rows; tile_row++) {
-            int row_off = f->frame_hdr->tiling.row_start_sb[tile_row] *
-                          f->sb_step * 4 * f->sb128w * 128;
-            int b_diff = (f->frame_hdr->tiling.row_start_sb[tile_row + 1] -
-                          f->frame_hdr->tiling.row_start_sb[tile_row]) * f->sb_step * 4;
+            const unsigned row_off = f->frame_hdr->tiling.row_start_sb[tile_row] *
+                                     sb_step4 * f->sb128w * 128;
+            const unsigned b_diff = (f->frame_hdr->tiling.row_start_sb[tile_row + 1] -
+                                     f->frame_hdr->tiling.row_start_sb[tile_row]) * sb_step4;
             for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
                 f->frame_thread.tile_start_off[tile_idx++] = row_off + b_diff *
-                    f->frame_hdr->tiling.col_start_sb[tile_col] * f->sb_step * 4;
+                    f->frame_hdr->tiling.col_start_sb[tile_col] * sb_step4;
             }
         }
 
index eceda98eca4dad20e96c3b0305ff8cf685669441..0ab1f2b5be9c093fe7cfdb88784b0b39562936b4 100644 (file)
@@ -292,7 +292,7 @@ struct Dav1dFrameContext {
         int prog_sz;
         int pal_sz, pal_idx_sz, cf_sz;
         // start offsets per tile
-        int *tile_start_off;
+        unsigned *tile_start_off;
     } frame_thread;
 
     // loopfilter