From f33e18ab393daa0b429273230bf8e4dd6856d139 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Fri, 11 Oct 2024 10:14:33 -0500 Subject: [PATCH] vulkan/queue: Check for _mem_signal_temp before we submit vk_queue_push_submit() takes ownership of the vk_queue_submit object and potentially passes it to another thread. This fixes a race where, if the other thread processes and deletes the vk_queue_submit before we get to checking _mem_signal_temp, we may have a use-after-free. Fixes: c95b646e234d ("vulkan/queue: Use _mem_signal_temp instead of signal_mem_sync") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11988 Reviewed-by: Juan A. Suarez Part-of: --- src/vulkan/runtime/vk_queue.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/vulkan/runtime/vk_queue.c b/src/vulkan/runtime/vk_queue.c index 172095452ce..5e03564adb2 100644 --- a/src/vulkan/runtime/vk_queue.c +++ b/src/vulkan/runtime/vk_queue.c @@ -1184,18 +1184,20 @@ vk_queue_submit(struct vk_queue *queue, } } + /* If we're signaling a memory object, we have to ensure that + * vkQueueSubmit does not return until the kernel submission has + * happened. Otherwise, we may get a race between this process + * and whatever is going to wait on the object where the other + * process may wait before we've submitted our work. Drain the + * queue now to avoid this. It's the responsibility of the caller + * to ensure that any vkQueueSubmit which signals a memory object + * has fully resolved dependencies. + */ + const bool needs_drain = submit->_mem_signal_temp; + vk_queue_push_submit(queue, submit); - if (submit->_mem_signal_temp != NULL) { - /* If we're signaling a memory object, we have to ensure that - * vkQueueSubmit does not return until the kernel submission has - * happened. Otherwise, we may get a race between this process - * and whatever is going to wait on the object where the other - * process may wait before we've submitted our work. Drain the - * queue now to avoid this. It's the responsibility of the caller - * to ensure that any vkQueueSubmit which signals a memory object - * has fully resolved dependencies. - */ + if (needs_drain) { result = vk_queue_drain(queue); if (unlikely(result != VK_SUCCESS)) return result;