Skip to content

Commit 1926a6b

Browse files
author
Thomas Hellström
committed
drm/i915: Fix vm use-after-free in vma destruction
In vma destruction, the following race may occur: Thread 1: Thread 2: i915_vma_destroy(); ... list_del_init(vma->vm_link); ... mutex_unlock(vma->vm->mutex); __i915_vm_release(); release_references(); And in release_reference() we dereference vma->vm to get to the vm gt pointer, leading to a use-after free. However, __i915_vm_release() grabs the vm->mutex so the vm won't be destroyed before vma->vm->mutex is released, so extract the gt pointer under the vm->mutex to avoid the vma->vm dereference in release_references(). v2: Fix a typo in the commit message (Andi Shyti) Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5944 Fixes: e1a7ab4 ("drm/i915: Remove the vm open count") Cc: Niranjana Vishwanathapura <[email protected]> Cc: Matthew Auld <[email protected]> Signed-off-by: Thomas Hellström <[email protected]> Acked-by: Nirmoy Das <[email protected]> Reviewed-by: Andrzej Hajda <[email protected]> Reviewed-by: Matthew Auld <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 99c0b3c commit 1926a6b

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

drivers/gpu/drm/i915/i915_vma.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,10 +1646,10 @@ static void force_unbind(struct i915_vma *vma)
16461646
GEM_BUG_ON(drm_mm_node_allocated(&vma->node));
16471647
}
16481648

1649-
static void release_references(struct i915_vma *vma, bool vm_ddestroy)
1649+
static void release_references(struct i915_vma *vma, struct intel_gt *gt,
1650+
bool vm_ddestroy)
16501651
{
16511652
struct drm_i915_gem_object *obj = vma->obj;
1652-
struct intel_gt *gt = vma->vm->gt;
16531653

16541654
GEM_BUG_ON(i915_vma_is_active(vma));
16551655

@@ -1704,20 +1704,24 @@ void i915_vma_destroy_locked(struct i915_vma *vma)
17041704

17051705
force_unbind(vma);
17061706
list_del_init(&vma->vm_link);
1707-
release_references(vma, false);
1707+
release_references(vma, vma->vm->gt, false);
17081708
}
17091709

17101710
void i915_vma_destroy(struct i915_vma *vma)
17111711
{
1712+
struct intel_gt *gt;
17121713
bool vm_ddestroy;
17131714

17141715
mutex_lock(&vma->vm->mutex);
17151716
force_unbind(vma);
17161717
list_del_init(&vma->vm_link);
17171718
vm_ddestroy = vma->vm_ddestroy;
17181719
vma->vm_ddestroy = false;
1720+
1721+
/* vma->vm may be freed when releasing vma->vm->mutex. */
1722+
gt = vma->vm->gt;
17191723
mutex_unlock(&vma->vm->mutex);
1720-
release_references(vma, vm_ddestroy);
1724+
release_references(vma, gt, vm_ddestroy);
17211725
}
17221726

17231727
void i915_vma_parked(struct intel_gt *gt)

0 commit comments

Comments
 (0)