mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 15:58:05 +02:00
amd/virtio: fix bo use-after-free race condition in amdvgpu_bo_free
In amdvgpu_bo_free(), when the reference count drops to 0, vdrm_flush() is called before removing the bo from the handle_to_vbo hash table. Since vdrm_flush() is a time-consuming operation and is executed outside of the handle_to_vbo_mutex lock, another thread calling amdvgpu_bo_import() can concurrently find this bo in the hash table, increment its refcount, and attempt to use it. Once vdrm_flush() finishes, amdvgpu_bo_free() proceeds to remove the bo and call free(), leaving the importing thread with a dangling pointer, which leads to a use-after-free or double free crash. To fix this race condition, we must remove the bo from the hash table under the lock first. After the bo is safely unlinked and the lock is released, we can then perform the time-consuming vdrm_flush() and the actual memory release. Signed-off-by: zhaqian <zhaqian@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41146>
This commit is contained in:
parent
9960637b26
commit
da7ed1c576
1 changed files with 8 additions and 6 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2024 Advanced Micro Devices, Inc.
|
||||
* Copyright 2026 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
|
@ -125,27 +125,29 @@ int amdvgpu_bo_export(amdvgpu_device_handle dev, amdvgpu_bo_handle bo,
|
|||
}
|
||||
|
||||
int amdvgpu_bo_free(amdvgpu_device_handle dev, struct amdvgpu_bo *bo) {
|
||||
simple_mtx_lock(&dev->handle_to_vbo_mutex);
|
||||
int refcnt = p_atomic_dec_return(&bo->refcount);
|
||||
|
||||
if (refcnt == 0) {
|
||||
/* Flush pending ops. */
|
||||
vdrm_flush(dev->vdev);
|
||||
|
||||
/* Remove it from the bo table. */
|
||||
if (bo->host_blob->handle > 0) {
|
||||
simple_mtx_lock(&dev->handle_to_vbo_mutex);
|
||||
void *entry = _mesa_hash_table_u64_search(dev->handle_to_vbo, bo->host_blob->handle);
|
||||
if (entry) {
|
||||
/* entry can be NULL for the shmem buffer. */
|
||||
_mesa_hash_table_u64_remove(dev->handle_to_vbo, bo->host_blob->handle);
|
||||
}
|
||||
simple_mtx_unlock(&dev->handle_to_vbo_mutex);
|
||||
}
|
||||
simple_mtx_unlock(&dev->handle_to_vbo_mutex);
|
||||
|
||||
/* Flush pending ops. */
|
||||
vdrm_flush(dev->vdev);
|
||||
|
||||
if (bo->host_blob)
|
||||
destroy_host_blob(dev, bo->host_blob);
|
||||
|
||||
free(bo);
|
||||
} else {
|
||||
simple_mtx_unlock(&dev->handle_to_vbo_mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue