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

please let me know if you want me to split it into two different MR

```
_____________________________________________________________________________________________
*** CID 1700498:         Memory - corruptions  (OVERRUN)
/media/ffvpx/libavcodec/vulkan_av1.c: 578             in vk_av1_decode_slice()
572     
573         /* Too many tiles, exceeding all defined levels in the AV1 spec */
574         if (ap->av1_pic_info.tileCount > MAX_TILES)
575             return AVERROR(ENOSYS);
576     
577         for (int i = s->tg_start; i <= s->tg_end; i++) {
>>>     CID 1700498:         Memory - corruptions  (OVERRUN)
>>>     Overrunning array "ap->tile_sizes" of 256 4-byte elements at element 
>>> index 256 (byte offset 1027) using index "ap->av1_pic_info.tileCount" 
>>> (which evaluates to 256).
578             ap->tile_sizes[ap->av1_pic_info.tileCount] = 
s->tile_group_info[i].tile_size;
579     
580             err = ff_vk_decode_add_slice(avctx, vp,
581                                          data + 
s->tile_group_info[i].tile_offset,
582                                          s->tile_group_info[i].tile_size, 0,
583                                          &ap->av1_pic_info.tileCount,
```

```

_____________________________________________________________________________________________
*** CID 1591875:         Incorrect expression  (SIZEOF_MISMATCH)
/media/ffvpx/libavcodec/vulkan_decode.c: 315             in 
ff_vk_decode_add_slice()
309     
310         size_t new_size = vp->slices_size + startcode_len + size +
311                           ctx->caps.minBitstreamBufferSizeAlignment;
312         new_size = FFALIGN(new_size, 
ctx->caps.minBitstreamBufferSizeAlignment);
313     
314         if (offsets) {
>>>     CID 1591875:         Incorrect expression  (SIZEOF_MISMATCH)
>>>     Passing argument "dec->slice_off" of type "uint32_t *" and argument 
>>> "(nb + 1) * 8UL /* sizeof (slice_off) */" to function "av_fast_realloc" is 
>>> suspicious.
315             slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
316                                         (nb + 1)*sizeof(slice_off));
317             if (!slice_off)
318                 return AVERROR(ENOMEM);
319     
320             *offsets = dec->slice_off = slice_off;

```


>From b3b9c966fe81ad22fdbc1f2f1ee4e6a59bf70830 Mon Sep 17 00:00:00 2001
From: Sylvestre Ledru <[email protected]>
Date: Thu, 27 Aug 2026 13:04:52 +0200
Subject: [PATCH 1/2] vulkan_av1: fix out-of-bounds write of tile_sizes

The tile count limit was only checked once on entry, but tileCount is
incremented by ff_vk_decode_add_slice() inside the loop, so a stream
carrying more than MAX_TILES tiles writes past the end of the
MAX_TILES-element tile_sizes array.

Check the limit on each iteration, and reject at MAX_TILES rather than
above it, since tileCount is used as the write index.
---
 libavcodec/vulkan_av1.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vulkan_av1.c b/libavcodec/vulkan_av1.c
index 97a8b9816f..99bdac46e5 100644
--- a/libavcodec/vulkan_av1.c
+++ b/libavcodec/vulkan_av1.c
@@ -570,11 +570,11 @@ static int vk_av1_decode_slice(AVCodecContext *avctx,
     AV1VulkanDecodePicture *ap = s->cur_frame.hwaccel_picture_private;
     FFVulkanDecodePicture *vp = &ap->vp;
 
-    /* Too many tiles, exceeding all defined levels in the AV1 spec */
-    if (ap->av1_pic_info.tileCount > MAX_TILES)
-        return AVERROR(ENOSYS);
-
     for (int i = s->tg_start; i <= s->tg_end; i++) {
+        /* Too many tiles, exceeding all defined levels in the AV1 spec */
+        if (ap->av1_pic_info.tileCount >= MAX_TILES)
+            return AVERROR(ENOSYS);
+
         ap->tile_sizes[ap->av1_pic_info.tileCount] = 
s->tile_group_info[i].tile_size;
 
         err = ff_vk_decode_add_slice(avctx, vp,
-- 
2.52.0


>From 5a39379527b4fc287d145fcc8fd7cf420d29003c Mon Sep 17 00:00:00 2001
From: Sylvestre Ledru <[email protected]>
Date: Thu, 27 Aug 2026 13:04:52 +0200
Subject: [PATCH 2/2] vulkan_decode: use the pointee size when growing
 slice_off

sizeof(slice_off) is the size of the uint32_t pointer, not of an entry.
Harmless in practice as it over-allocates on 64-bit, but wrong, and
under-allocates on targets where a pointer is smaller than uint32_t.
---
 libavcodec/vulkan_decode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index dd5fbb4496..ab313423e5 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -255,7 +255,7 @@ int ff_vk_decode_add_slice(AVCodecContext *avctx, 
FFVulkanDecodePicture *vp,
 
     if (offsets) {
         slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
-                                    (nb + 1)*sizeof(slice_off));
+                                    (nb + 1)*sizeof(*slice_off));
         if (!slice_off)
             return AVERROR(ENOMEM);
 
-- 
2.52.0

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

Reply via email to