PR #23788 opened by Lynne URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23788 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23788.patch
Fixes a minor use-after-free, and invalid SPIR-V generation. Makes all tests pass. >From 076ad9bed369f41731180deb8e1be712d00889a0 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Mon, 13 Jul 2026 00:13:59 +0900 Subject: [PATCH 1/2] swscale/vulkan: fix invalid SPIR-V generation for plane-remapped passes The CLEAR codegen iterated components by value[i].den, while the constants pass iterates by clear.mask; unmasked components may hold leftover values with a nonzero denominator, consuming more constant IDs than were registered and emitting ID 0 into the instruction stream. The image handle arrays were also sized by the number of planes an op touches, but plane_src/plane_dst contain actual frame plane indices, so a pass writing only e.g. the alpha plane references handle 3 while only handle 0 was loaded. Either results in invalid SPIR-V, which crashes RADV inside spirv_to_nir when creating the shader object. --- libswscale/vulkan/ops.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index 045f220745..54f1c689eb 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -908,6 +908,16 @@ static int read_filtered(SPICtx *spi, SPIRVIDs *id, const SwsOpList *ops, acc_s[0], acc_s[1], acc_s[2], acc_s[3]); } +/* Plane indices refer to actual frame planes, so the image handle arrays + * have to cover the highest plane referenced, not just the plane count. */ +static int rw_op_img_count(const SwsOp *op, const uint8_t *planes) +{ + int count = 0; + for (int i = 0; i < ff_sws_rw_op_planes(op); i++) + count = FFMAX(count, planes[i] + 1); + return count; +} + static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s, const SwsOpList *ops, FFVulkanShader *shd) { @@ -929,11 +939,11 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s, /* Image ops, to determine types */ const SwsOp *op_w = ff_sws_op_list_output(ops); - int out_img_count = ff_sws_rw_op_planes(op_w); + int out_img_count = rw_op_img_count(op_w, ops->plane_dst); p->dst_rep = op_w->type == SWS_PIXEL_F32 ? FF_VK_REP_FLOAT : FF_VK_REP_UINT; const SwsOp *op_r = ff_sws_op_list_input(ops); - int in_img_count = op_r ? ff_sws_rw_op_planes(op_r) : 0; + int in_img_count = op_r ? rw_op_img_count(op_r, ops->plane_src) : 0; if (op_r) p->src_rep = op_r->type == SWS_PIXEL_F32 ? FF_VK_REP_FLOAT : FF_VK_REP_UINT; @@ -1038,7 +1048,7 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s, } /* Load output image handles */ - int out_img[4]; + int out_img[4] = { 0 }; for (int i = 0; i < out_img_count; i++) { int img = spi_OpAccessChain(spi, id->out_img_sptr, id->in_vars[2], id->u32_cid[i]); @@ -1171,7 +1181,7 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s, break; case SWS_OP_CLEAR: for (int i = 0; i < 4; i++) { - if (!op->clear.value[i].den) + if (!SWS_COMP_TEST(op->clear.mask, i)) continue; data = spi_OpCompositeInsert(spi, type_v, id->const_ids[nb_const_ids++], -- 2.52.0 >From 9d6c9fe47a53d4691bb4b68d1ad23b3700aa4974 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Mon, 13 Jul 2026 00:13:59 +0900 Subject: [PATCH 2/2] swscale/ops_dispatch: fix use-after-free when adding opaque ops passes comp points into p, which is freed before comp->backend is read. Use the copy taken before the free. --- libswscale/ops_dispatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/ops_dispatch.c b/libswscale/ops_dispatch.c index dd166a5f92..2da38fc333 100644 --- a/libswscale/ops_dispatch.c +++ b/libswscale/ops_dispatch.c @@ -550,7 +550,7 @@ static int compile_single(const CompileArgs *args, const SwsOpList *ops, input, 0, c.slice_align, c.func_opaque, NULL, c.priv, c.free, output); if (ret >= 0) { - (*output)->backend = comp->backend->flags; + (*output)->backend = c.backend->flags; ff_sws_pass_link_output(*output, link); } return ret; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
