Module: Mesa Branch: main Commit: aeeb0b4deb3f3b2ddfdc5aa01883764e748a1b88 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=aeeb0b4deb3f3b2ddfdc5aa01883764e748a1b88
Author: Konstantin Seurer <[email protected]> Date: Tue Apr 19 12:20:08 2022 +0200 radv: Copy shader modules to avoid use after free The vkd3d-proton ray tracing tests delete shader modules after creating pipeline libraries from them. This resulted in a use after free when creating ray tracing pipelines. Signed-off-by: Konstantin Seurer <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16027> --- src/amd/vulkan/radv_pipeline.c | 5 +++++ src/amd/vulkan/radv_pipeline_rt.c | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 4d1a02f73ce..985b5129708 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -240,6 +240,11 @@ radv_pipeline_destroy(struct radv_device *device, struct radv_pipeline *pipeline free(pipeline->compute.rt_stack_sizes); } else if (pipeline->type == RADV_PIPELINE_LIBRARY) { free(pipeline->library.groups); + for (uint32_t i = 0; i < pipeline->library.stage_count; i++) { + RADV_FROM_HANDLE(vk_shader_module, module, pipeline->library.stages[i].module); + vk_object_base_finish(&module->base); + ralloc_free(module); + } free(pipeline->library.stages); } diff --git a/src/amd/vulkan/radv_pipeline_rt.c b/src/amd/vulkan/radv_pipeline_rt.c index cb94ede62da..02d27ef8942 100644 --- a/src/amd/vulkan/radv_pipeline_rt.c +++ b/src/amd/vulkan/radv_pipeline_rt.c @@ -109,12 +109,21 @@ radv_rt_pipeline_library_create(VkDevice _device, VkPipelineCache _cache, goto fail; if (local_create_info.stageCount) { - size_t size = sizeof(VkPipelineShaderStageCreateInfo) * local_create_info.stageCount; pipeline->library.stage_count = local_create_info.stageCount; + + size_t size = sizeof(VkPipelineShaderStageCreateInfo) * local_create_info.stageCount; pipeline->library.stages = malloc(size); if (!pipeline->library.stages) goto fail; + memcpy(pipeline->library.stages, local_create_info.pStages, size); + + for (uint32_t i = 0; i < local_create_info.stageCount; i++) { + RADV_FROM_HANDLE(vk_shader_module, module, pipeline->library.stages[i].module); + + struct vk_shader_module *new_module = vk_shader_module_clone(NULL, module); + pipeline->library.stages[i].module = vk_shader_module_to_handle(new_module); + } } if (local_create_info.groupCount) {
