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) {

Reply via email to