Skip to content

Commit

Permalink
drm/xe/vm: move xa_alloc to prevent UAF
Browse files Browse the repository at this point in the history
Evil user can guess the next id of the vm before the ioctl completes and
then call vm destroy ioctl to trigger UAF since create ioctl is still
referencing the same vm. Move the xa_alloc all the way to the end to
prevent this.

v2:
 - Rebase

Fixes: dd08ebf ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Signed-off-by: Matthew Auld <[email protected]>
Cc: Matthew Brost <[email protected]>
Cc: <[email protected]> # v6.8+
Reviewed-by: Nirmoy Das <[email protected]>
Reviewed-by: Matthew Brost <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
(cherry picked from commit dcfd397)
Signed-off-by: Lucas De Marchi <[email protected]>
  • Loading branch information
matt-auld authored and lucasdemarchi committed Oct 3, 2024
1 parent 9e3c85d commit 7423187
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions drivers/gpu/drm/xe/xe_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1765,23 +1765,18 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,
if (IS_ERR(vm))
return PTR_ERR(vm);

err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
if (err)
goto err_close_and_put;

if (xe->info.has_asid) {
down_write(&xe->usm.lock);
err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm,
XA_LIMIT(1, XE_MAX_ASID - 1),
&xe->usm.next_asid, GFP_KERNEL);
up_write(&xe->usm.lock);
if (err < 0)
goto err_free_id;
goto err_close_and_put;

vm->usm.asid = asid;
}

args->vm_id = id;
vm->xef = xe_file_get(xef);

/* Record BO memory for VM pagetable created against client */
Expand All @@ -1794,10 +1789,15 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,
args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE);
#endif

/* user id alloc must always be last in ioctl to prevent UAF */
err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
if (err)
goto err_close_and_put;

args->vm_id = id;

return 0;

err_free_id:
xa_erase(&xef->vm.xa, id);
err_close_and_put:
xe_vm_close_and_put(vm);

Expand Down

0 comments on commit 7423187

Please sign in to comment.