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: c95b646e23 ("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 <jasuarez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31597>
This commit is contained in:
Faith Ekstrand
2024-10-11 10:14:33 -05:00
committed by Marge Bot
parent 980d0e2d06
commit f33e18ab39
+12 -10
View File
@@ -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;