Commit 83967c57 authored by Matthew Auld's avatar Matthew Auld

drm/xe/vm: prevent UAF with asid based lookup

The asid is only erased from the xarray when the vm refcount reaches
zero, however this leads to potential UAF since the xe_vm_get() only
works on a vm with refcount != 0. Since the asid is allocated in the vm
create ioctl, rather erase it when closing the vm, prior to dropping the
potential last ref. This should also work when user closes driver fd
without explicit vm destroy.

Fixes: dd08ebf6 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/1594Signed-off-by: default avatarMatthew Auld <matthew.auld@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <stable@vger.kernel.org> # v6.8+
Reviewed-by: default avatarMatthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240412113144.259426-4-matthew.auld@intel.com
parent 48b1f11c
...@@ -1481,6 +1481,16 @@ void xe_vm_close_and_put(struct xe_vm *vm) ...@@ -1481,6 +1481,16 @@ void xe_vm_close_and_put(struct xe_vm *vm)
xe->usm.num_vm_in_fault_mode--; xe->usm.num_vm_in_fault_mode--;
else if (!(vm->flags & XE_VM_FLAG_MIGRATION)) else if (!(vm->flags & XE_VM_FLAG_MIGRATION))
xe->usm.num_vm_in_non_fault_mode--; xe->usm.num_vm_in_non_fault_mode--;
if (vm->usm.asid) {
void *lookup;
xe_assert(xe, xe->info.has_asid);
xe_assert(xe, !(vm->flags & XE_VM_FLAG_MIGRATION));
lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
xe_assert(xe, lookup == vm);
}
mutex_unlock(&xe->usm.lock); mutex_unlock(&xe->usm.lock);
for_each_tile(tile, xe, id) for_each_tile(tile, xe, id)
...@@ -1496,24 +1506,15 @@ static void vm_destroy_work_func(struct work_struct *w) ...@@ -1496,24 +1506,15 @@ static void vm_destroy_work_func(struct work_struct *w)
struct xe_device *xe = vm->xe; struct xe_device *xe = vm->xe;
struct xe_tile *tile; struct xe_tile *tile;
u8 id; u8 id;
void *lookup;
/* xe_vm_close_and_put was not called? */ /* xe_vm_close_and_put was not called? */
xe_assert(xe, !vm->size); xe_assert(xe, !vm->size);
mutex_destroy(&vm->snap_mutex); mutex_destroy(&vm->snap_mutex);
if (!(vm->flags & XE_VM_FLAG_MIGRATION)) { if (!(vm->flags & XE_VM_FLAG_MIGRATION))
xe_device_mem_access_put(xe); xe_device_mem_access_put(xe);
if (xe->info.has_asid && vm->usm.asid) {
mutex_lock(&xe->usm.lock);
lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
xe_assert(xe, lookup == vm);
mutex_unlock(&xe->usm.lock);
}
}
for_each_tile(tile, xe, id) for_each_tile(tile, xe, id)
XE_WARN_ON(vm->pt_root[id]); XE_WARN_ON(vm->pt_root[id]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment