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


>From 21017c72db251d843f9aa710ac15c00c78585c6f Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:10 +0200
Subject: [PATCH 01/10] avcodec/vdpau_hevc: reject tile counts the VDPAU
 picture info cannot hold

Fixes: 71WWW3jyHksv
Fixes: AISLE-2026-0150-00422
Fixes: out of array write
Out of array write Replicated through UnModified FFmpeg with ASAN and UBSAN
using a stub VDPAU driver

Found-by: Joshua Rogers (AISLE)

The report suggested rejecting tile counts beyond the array sizes.
---
 libavcodec/vdpau_hevc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c
index 1a92c32b27..100611ab2b 100644
--- a/libavcodec/vdpau_hevc.c
+++ b/libavcodec/vdpau_hevc.c
@@ -150,6 +150,11 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
     info->tiles_enabled_flag = pps->tiles_enabled_flag;
     info->entropy_coding_sync_enabled_flag = 
pps->entropy_coding_sync_enabled_flag;
     if (info->tiles_enabled_flag) {
+        if (pps->num_tile_columns > FF_ARRAY_ELEMS(info->column_width_minus1) 
||
+            pps->num_tile_rows    > FF_ARRAY_ELEMS(info->row_height_minus1)) {
+            av_log(avctx, AV_LOG_ERROR, "Too many tiles\n");
+            return AVERROR(ENOSYS);
+        }
         /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
         info->num_tile_columns_minus1 = pps->num_tile_columns - 1;
         /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
-- 
2.54.0


>From 3cd298c0d8b12b232296cde702b37ba9c84fc9d5 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:10 +0200
Subject: [PATCH 02/10] avcodec/vaapi_hevc: reject tile counts the VAAPI
 picture parameters cannot hold

Fixes: 6ZyaPaO9BN6r
Fixes: AISLE-2026-0150-00198
Fixes: out of array write
Out of array write Replicated through UnModified FFmpeg with ASAN and UBSAN
using a stub VAAPI driver

Found-by: Joshua Rogers (AISLE)

The report suggested rejecting tile counts beyond the array sizes.
---
 libavcodec/vaapi_hevc.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index 878f7965c4..a9c08b59c4 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -214,13 +214,18 @@ static int vaapi_hevc_start_frame(AVCodecContext          
*avctx,
     fill_vaapi_reference_frames(h, l, pic_param);
 
     if (pps->tiles_enabled_flag) {
+        if (pps->num_tile_columns > 
FF_ARRAY_ELEMS(pic_param->column_width_minus1) + 1 ||
+            pps->num_tile_rows    > 
FF_ARRAY_ELEMS(pic_param->row_height_minus1) + 1) {
+            av_log(avctx, AV_LOG_ERROR, "Too many tiles\n");
+            return AVERROR(ENOSYS);
+        }
         pic_param->num_tile_columns_minus1 = pps->num_tile_columns - 1;
         pic_param->num_tile_rows_minus1    = pps->num_tile_rows - 1;
 
-        for (i = 0; i < pps->num_tile_columns; i++)
+        for (i = 0; i < FFMIN(pps->num_tile_columns, 
FF_ARRAY_ELEMS(pic_param->column_width_minus1)); i++)
             pic_param->column_width_minus1[i] = pps->column_width[i] - 1;
 
-        for (i = 0; i < pps->num_tile_rows; i++)
+        for (i = 0; i < FFMIN(pps->num_tile_rows, 
FF_ARRAY_ELEMS(pic_param->row_height_minus1)); i++)
             pic_param->row_height_minus1[i] = pps->row_height[i] - 1;
     }
 
-- 
2.54.0


>From a4983189482bd8e957c06b45ac49473f8e08cd01 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:10 +0200
Subject: [PATCH 03/10] avcodec/dxva2_hevc: reject tile counts the DXVA picture
 parameters cannot hold

Not replicated, no DXVA capable system is available here.

Fixes: BluA5ZxmGiNN
Fixes: AISLE-2026-0150-00637

Found-by: Joshua Rogers (AISLE)

The report suggested rejecting tile counts beyond the array sizes.
---
 libavcodec/d3d12va_hevc.c   |  3 ++-
 libavcodec/dxva2_hevc.c     | 16 ++++++++++++----
 libavcodec/dxva2_internal.h |  2 +-
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libavcodec/d3d12va_hevc.c b/libavcodec/d3d12va_hevc.c
index 1b73b2d0b6..25a1316bb9 100644
--- a/libavcodec/d3d12va_hevc.c
+++ b/libavcodec/d3d12va_hevc.c
@@ -65,7 +65,8 @@ static int d3d12va_hevc_start_frame(AVCodecContext *avctx,
 
     ctx->used_mask = 0;
 
-    ff_dxva2_hevc_fill_picture_parameters(avctx, (AVDXVAContext *)ctx, 
&ctx_pic->pp);
+    if (ff_dxva2_hevc_fill_picture_parameters(avctx, (AVDXVAContext *)ctx, 
&ctx_pic->pp) < 0)
+        return -1;
 
     ff_dxva2_hevc_fill_scaling_lists(avctx, (AVDXVAContext *)ctx, 
&ctx_pic->qm);
 
diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
index 85698dfcce..c5e3600f21 100644
--- a/libavcodec/dxva2_hevc.c
+++ b/libavcodec/dxva2_hevc.c
@@ -57,7 +57,7 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, 
int surface_index)
     return 0xff;
 }
 
-void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, 
AVDXVAContext *ctx,
+int ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, 
AVDXVAContext *ctx,
                                     DXVA_PicParams_HEVC *pp)
 {
     const HEVCContext *h = avctx->priv_data;
@@ -143,14 +143,19 @@ void ff_dxva2_hevc_fill_picture_parameters(const 
AVCodecContext *avctx, AVDXVACo
     pp->pps_cb_qp_offset            = pps->cb_qp_offset;
     pp->pps_cr_qp_offset            = pps->cr_qp_offset;
     if (pps->tiles_enabled_flag) {
+        if (pps->num_tile_columns > FF_ARRAY_ELEMS(pp->column_width_minus1) + 
1 ||
+            pps->num_tile_rows    > FF_ARRAY_ELEMS(pp->row_height_minus1) + 1) 
{
+            av_log((void *)avctx, AV_LOG_ERROR, "Too many tiles\n");
+            return AVERROR(ENOSYS);
+        }
         pp->num_tile_columns_minus1 = pps->num_tile_columns - 1;
         pp->num_tile_rows_minus1    = pps->num_tile_rows - 1;
 
         if (!pps->uniform_spacing_flag) {
-            for (i = 0; i < pps->num_tile_columns; i++)
+            for (i = 0; i < FFMIN(pps->num_tile_columns, 
FF_ARRAY_ELEMS(pp->column_width_minus1)); i++)
                 pp->column_width_minus1[i] = pps->column_width[i] - 1;
 
-            for (i = 0; i < pps->num_tile_rows; i++)
+            for (i = 0; i < FFMIN(pps->num_tile_rows, 
FF_ARRAY_ELEMS(pp->row_height_minus1)); i++)
                 pp->row_height_minus1[i] = pps->row_height[i] - 1;
         }
     }
@@ -200,6 +205,8 @@ void ff_dxva2_hevc_fill_picture_parameters(const 
AVCodecContext *avctx, AVDXVACo
     DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
 
     pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
+
+    return 0;
 }
 
 void ff_dxva2_hevc_fill_scaling_lists(const AVCodecContext *avctx, 
AVDXVAContext *ctx, DXVA_Qmatrix_HEVC *qm)
@@ -376,7 +383,8 @@ static int dxva2_hevc_start_frame(AVCodecContext *avctx,
     av_assert0(ctx_pic);
 
     /* Fill up DXVA_PicParams_HEVC */
-    ff_dxva2_hevc_fill_picture_parameters(avctx, ctx, &ctx_pic->pp);
+    if (ff_dxva2_hevc_fill_picture_parameters(avctx, ctx, &ctx_pic->pp) < 0)
+        return -1;
 
     /* Fill up DXVA_Qmatrix_HEVC */
     ff_dxva2_hevc_fill_scaling_lists(avctx, ctx, &ctx_pic->qm);
diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
index 6cbd0e42d7..31826b073f 100644
--- a/libavcodec/dxva2_internal.h
+++ b/libavcodec/dxva2_internal.h
@@ -172,7 +172,7 @@ void ff_dxva2_h264_fill_picture_parameters(const 
AVCodecContext *avctx, AVDXVACo
 void ff_dxva2_h264_fill_scaling_lists(const AVCodecContext *avctx, 
AVDXVAContext *ctx, DXVA_Qmatrix_H264 *qm);
 
 #if CONFIG_HEVC_D3D12VA_HWACCEL || CONFIG_HEVC_D3D11VA_HWACCEL || 
CONFIG_HEVC_D3D11VA2_HWACCEL || CONFIG_HEVC_DXVA2_HWACCEL
-void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, 
AVDXVAContext *ctx, DXVA_PicParams_HEVC *pp);
+int ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, 
AVDXVAContext *ctx, DXVA_PicParams_HEVC *pp);
 
 void ff_dxva2_hevc_fill_scaling_lists(const AVCodecContext *avctx, 
AVDXVAContext *ctx, DXVA_Qmatrix_HEVC *qm);
 #endif
-- 
2.54.0


>From d385fd442af4a4aa8967a4c3fe9f80dbebc11159 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:10 +0200
Subject: [PATCH 04/10] avcodec/vulkan_hevc: reject tile counts the Vulkan PPS
 cannot hold

Fixes: sG5Hl4tXqkD5
Fixes: out of array write
Out of array write Replicated through UnModified FFmpeg with UBSAN

Found during triage/review of the security report AISLE-2026-R0043
---
 libavcodec/vulkan_hevc.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/libavcodec/vulkan_hevc.c b/libavcodec/vulkan_hevc.c
index 6c0cd56363..c8badf692f 100644
--- a/libavcodec/vulkan_hevc.c
+++ b/libavcodec/vulkan_hevc.c
@@ -450,11 +450,15 @@ static void set_sps(const HEVCSPS *sps, int sps_idx,
     };
 }
 
-static void set_pps(const HEVCPPS *pps, const HEVCSPS *sps,
-                    StdVideoH265ScalingLists *vkpps_scaling,
-                    StdVideoH265PictureParameterSet *vkpps,
-                    StdVideoH265PredictorPaletteEntries *pal)
+static int set_pps(const HEVCPPS *pps, const HEVCSPS *sps,
+                   StdVideoH265ScalingLists *vkpps_scaling,
+                   StdVideoH265PictureParameterSet *vkpps,
+                   StdVideoH265PredictorPaletteEntries *pal)
 {
+    if (pps->num_tile_columns > FF_ARRAY_ELEMS(vkpps->column_width_minus1) + 1 
||
+        pps->num_tile_rows    > FF_ARRAY_ELEMS(vkpps->row_height_minus1) + 1)
+        return AVERROR(ENOSYS);
+
     copy_scaling_list(&pps->scaling_list, vkpps_scaling);
 
     *vkpps = (StdVideoH265PictureParameterSet) {
@@ -536,6 +540,8 @@ static void set_pps(const HEVCPPS *pps, const HEVCSPS *sps,
         vkpps->cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
         vkpps->cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
     }
+
+    return 0;
 }
 
 static void set_vps(const HEVCVPS *vps,
@@ -680,8 +686,10 @@ static int vk_hevc_create_params(AVCodecContext *avctx, 
VkVideoSessionParameters
             const HEVCPPS *pps_l = h->ps.pps_list[i];
             const HEVCSPS *sps_l = h->ps.sps_list[pps_l->sps_id];
             int idx = h265_params_info.stdPPSCount++;
-            set_pps(pps_l, sps_l, &hdr->hpps[idx].scaling,
-                    &hdr->pps[idx], &hdr->hpps[idx].pal);
+            err = set_pps(pps_l, sps_l, &hdr->hpps[idx].scaling,
+                          &hdr->pps[idx], &hdr->hpps[idx].pal);
+            if (err < 0)
+                return err;
         }
     }
 
@@ -887,7 +895,9 @@ static int vk_hevc_end_frame(AVCodecContext *avctx)
             return err;
         hdr = dec->hevc_headers;
 
-        set_pps(pps, sps, &hdr->hpps[0].scaling, &hdr->pps[0], 
&hdr->hpps[0].pal);
+        err = set_pps(pps, sps, &hdr->hpps[0].scaling, &hdr->pps[0], 
&hdr->hpps[0].pal);
+        if (err < 0)
+            return err;
         set_sps(sps, pps->sps_id, &hdr->hsps[0].scaling, 
&hdr->hsps[0].vui_header,
                 &hdr->hsps[0].vui, &hdr->sps[0], hdr->hsps[0].nal_hdr,
                 hdr->hsps[0].vcl_hdr, &hdr->hsps[0].ptl, &hdr->hsps[0].dpbm,
-- 
2.54.0


>From 09a668375476669cf6cbd538252e06f2a8109c25 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:10 +0200
Subject: [PATCH 05/10] avcodec/vulkan_decode: limit the slice data of a frame
 to 2 GiB

Not replicated.

Fixes: Jdy0O5Qn34O8
Fixes: AISLE-2026-0150-00708

Found-by: Joshua Rogers (AISLE)

The report suggested bounding the size and rounding it in 64 bits.
---
 libavcodec/vulkan_decode.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 34ca4dc565..38afdd85f4 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -249,9 +249,11 @@ int ff_vk_decode_add_slice(AVCodecContext *avctx, 
FFVulkanDecodePicture *vp,
     uint32_t *slice_off;
     FFVkBuffer *vkbuf;
 
-    size_t new_size = vp->slices_size + startcode_len + size +
-                      ctx->caps.minBitstreamBufferSizeAlignment;
+    uint64_t new_size = vp->slices_size + startcode_len + size +
+                        ctx->caps.minBitstreamBufferSizeAlignment;
     new_size = FFALIGN(new_size, ctx->caps.minBitstreamBufferSizeAlignment);
+    if (new_size > INT32_MAX)
+        return AVERROR(ENOSYS);
 
     if (offsets) {
         slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max,
@@ -274,7 +276,7 @@ int ff_vk_decode_add_slice(AVCodecContext *avctx, 
FFVulkanDecodePicture *vp,
 
         /* Align buffer to nearest power of two. Makes fragmentation management
          * easier, and gives us ample headroom. */
-        buf_size = 2 << av_log2(buf_size);
+        buf_size = 2ULL << av_log2(buf_size);
 
         /* When the frames context uses DRM modifier tiling,
          * hwctx->create_pnext contains 
VkImageDrmFormatModifierListCreateInfoEXT,
-- 
2.54.0


>From e4bc5888efbefb4e6ec2d9970d839806696ba1ca Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:11 +0200
Subject: [PATCH 06/10] avcodec/ffv1enc_vulkan: reject frames whose float remap
 data exceeds 4 GiB

Fixes: UfNaupCjUEh6
Fixes: AISLE-2026-0150-00707
Integer overflow Replicated through Modified FFmpeg printing the sizes

Found-by: Joshua Rogers (AISLE)

The report suggested rejecting slice layouts whose remap data exceeds the
32 bit limit.
---
 libavcodec/ffv1enc_vulkan.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c
index 699df37b6d..f3ded3d097 100644
--- a/libavcodec/ffv1enc_vulkan.c
+++ b/libavcodec/ffv1enc_vulkan.c
@@ -1362,6 +1362,11 @@ static av_cold int 
vulkan_encode_ffv1_init(AVCodecContext *avctx)
         if (n < 2)
             n = 2;
         fv->max_pixels_per_slice = n;
+
+        if ((uint64_t)n * 12 * sizeof(uint32_t) * f->max_slice_count > 
UINT32_MAX) {
+            av_log(avctx, AV_LOG_ERROR, "Frame too large for the float 
remap\n");
+            return AVERROR_PATCHWELCOME;
+        }
     }
 
     /* Init rct search shader */
-- 
2.54.0


>From 8973aced7862593ea504ca8a0f906aee6c651df1 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 16 Oct 2026 23:19:11 +0200
Subject: [PATCH 07/10] avcodec/dpx: release the hwaccel picture when the
 hwaccel fails

Fixes: IDrqnHVI4YX3
Fixes: AISLE-2026-0150-00625
Fixes: assertion failure
Assertion failure Replicated through Modified FFmpeg with a failure injected
into the Vulkan hwaccel, with -threads 1

Found-by: Joshua Rogers (AISLE)

The report suggested releasing the picture on the failure paths.
---
 libavcodec/dpx.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index a4d9348618..77404c204a 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -785,18 +785,14 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
         const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
 
         ret = hwaccel->start_frame(avctx, avpkt->buf, buf, avpkt->size - 
offset);
-        if (ret < 0)
-            return ret;
-
-        ret = hwaccel->decode_slice(avctx, buf, avpkt->size - offset);
-        if (ret < 0)
-            return ret;
-
-        ret = hwaccel->end_frame(avctx);
-        if (ret < 0)
-            return ret;
+        if (ret >= 0)
+            ret = hwaccel->decode_slice(avctx, buf, avpkt->size - offset);
+        if (ret >= 0)
+            ret = hwaccel->end_frame(avctx);
 
         av_refstruct_unref(&dpx->hwaccel_picture_private);
+        if (ret < 0)
+            return ret;
     } else {
         unpack_frame(avctx, p, buf, dpx->components, dpx->endian);
     }
-- 
2.54.0


>From ac00092b469b8782c8b560d6bde8cfe7f78d01b9 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Sat, 17 Oct 2026 00:57:16 +0200
Subject: [PATCH 08/10] avcodec/apv_decode: release the hwaccel picture when
 the hwaccel fails

Fixes: 233BfozgW6QZ
Fixes: assertion failure
Assertion failure Replicated through Modified FFmpeg with a failure injected
into the Vulkan hwaccel, with -threads 1

Found during triage/review of the security report AISLE-2026-R0043
---
 libavcodec/apv_decode.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/libavcodec/apv_decode.c b/libavcodec/apv_decode.c
index cde6593602..4d1b1194bb 100644
--- a/libavcodec/apv_decode.c
+++ b/libavcodec/apv_decode.c
@@ -394,24 +394,21 @@ static int apv_decode(AVCodecContext *avctx, AVFrame 
*output,
 
         err = hwaccel->start_frame(avctx, apv->pkt->buf,
                                    apv->pkt->data, apv->pkt->size);
-        if (err < 0)
-            return err;
 
-        for (int j = 0; j < desc->nb_components; j++) {
-            for (int i = 0; i < tile_info->num_tiles; i++) {
+        for (int j = 0; j < desc->nb_components && err >= 0; j++) {
+            for (int i = 0; i < tile_info->num_tiles && err >= 0; i++) {
                 APVRawTile *tile = &input->tile[i];
                 err = hwaccel->decode_slice(avctx, tile->tile_data[j],
                                             
tile->tile_header.tile_data_size[j]);
-                if (err < 0)
-                    return err;
             }
         }
 
-        err = hwaccel->end_frame(avctx);
-        if (err < 0)
-            return err;
+        if (err >= 0)
+            err = hwaccel->end_frame(avctx);
 
         av_refstruct_unref(&apv->hwaccel_picture_private);
+        if (err < 0)
+            return err;
     } else {
         // Each component within a tile is independent of every other,
         // so we can decode all in parallel.
-- 
2.54.0


>From f1094138eef3caf01253a48091dbd6f1ab819a2f Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Sat, 17 Oct 2026 00:57:16 +0200
Subject: [PATCH 09/10] avcodec/prores_raw: release the hwaccel picture when
 the hwaccel fails

Fixes: 233BfozgW6QZ
Fixes: assertion failure
Assertion failure Replicated through Modified FFmpeg with a failure injected
into the Vulkan hwaccel, with -threads 1

Found during triage/review of the security report AISLE-2026-R0043
---
 libavcodec/prores_raw.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c
index 36c3879f73..b475582860 100644
--- a/libavcodec/prores_raw.c
+++ b/libavcodec/prores_raw.c
@@ -560,22 +560,19 @@ static int decode_frame(AVCodecContext *avctx,
         const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
 
         ret = hwaccel->start_frame(avctx, avpkt->buf, avpkt->data, 
avpkt->size);
-        if (ret < 0)
-            return ret;
 
-        for (int n = 0; n < s->nb_tiles; n++) {
+        for (int n = 0; n < s->nb_tiles && ret >= 0; n++) {
             TileContext *tile = &s->tiles[n];
             ret = hwaccel->decode_slice(avctx, tile->gb.buffer,
                                         tile->gb.buffer_end - tile->gb.buffer);
-            if (ret < 0)
-                return ret;
         }
 
-        ret = hwaccel->end_frame(avctx);
-        if (ret < 0)
-            return ret;
+        if (ret >= 0)
+            ret = hwaccel->end_frame(avctx);
 
         av_refstruct_unref(&s->hwaccel_picture_private);
+        if (ret < 0)
+            return ret;
     } else {
         avctx->execute2(avctx, decode_tiles, frame, NULL, s->nb_tiles);
     }
-- 
2.54.0


>From daa4cd6fadfeffe4f7a59583df6c8bbfc5aee072 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Sat, 17 Oct 2026 00:57:17 +0200
Subject: [PATCH 10/10] avcodec/rw2dec: release the hwaccel picture when the
 hwaccel fails

Not replicated, no hwaccel exists for rw2 yet.

Fixes: 233BfozgW6QZ

Found during triage/review of the security report AISLE-2026-R0043
---
 libavcodec/rw2dec.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/libavcodec/rw2dec.c b/libavcodec/rw2dec.c
index 86dc6d95de..77dd335d7d 100644
--- a/libavcodec/rw2dec.c
+++ b/libavcodec/rw2dec.c
@@ -529,22 +529,19 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
         const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
 
         ret = hwaccel->start_frame(avctx, avpkt->buf, avpkt->data, 
avpkt->size);
-        if (ret < 0)
-            return ret;
 
-        for (int i = 0; i < h->nb_stripes; i++) {
+        for (int i = 0; i < h->nb_stripes && ret >= 0; i++) {
             const RW2Stripe *st = &h->stripes[i];
             ret = hwaccel->decode_slice(avctx, s->payload + st->offset,
                                         (st->size_bits + 7) >> 3);
-            if (ret < 0)
-                return ret;
         }
 
-        ret = hwaccel->end_frame(avctx);
-        if (ret < 0)
-            return ret;
+        if (ret >= 0)
+            ret = hwaccel->end_frame(avctx);
 
         av_refstruct_unref(&s->hwaccel_picture_private);
+        if (ret < 0)
+            return ret;
     } else {
         int rets[RW2_MAX_STRIPES];
 
-- 
2.54.0

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

Reply via email to