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:pull/843/head^2dd08ebf6c3("drm/xe: Introduce a new DRM driver for Intel GPUs") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/1594 Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240412113144.259426-4-matthew.auld@intel.com (cherry picked from commit83967c5732) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
parent
652ead9b74
commit
ca7c52ac7a
|
|
@ -1577,6 +1577,16 @@ void xe_vm_close_and_put(struct xe_vm *vm)
|
|||
xe->usm.num_vm_in_fault_mode--;
|
||||
else if (!(vm->flags & XE_VM_FLAG_MIGRATION))
|
||||
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);
|
||||
|
||||
for_each_tile(tile, xe, id)
|
||||
|
|
@ -1592,24 +1602,15 @@ static void vm_destroy_work_func(struct work_struct *w)
|
|||
struct xe_device *xe = vm->xe;
|
||||
struct xe_tile *tile;
|
||||
u8 id;
|
||||
void *lookup;
|
||||
|
||||
/* xe_vm_close_and_put was not called? */
|
||||
xe_assert(xe, !vm->size);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
XE_WARN_ON(vm->pt_root[id]);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue