Message ID | 20220620123659.381772-1-thomas.hellstrom@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] drm/i915: Fix vm use-after-free in vma destruction | expand |
Acked-by: Nirmoy Das <nirmoy.das@intel.con> On 6/20/2022 2:36 PM, Thomas Hellström wrote: > 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: e1a7ab4fca ("drm/i915: Remove the vm open count") > > Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > Cc: Matthew Auld <matthew.auld@intel.com> > Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_vma.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c > index 0bffb70b3c5f..04d12f278f57 100644 > --- a/drivers/gpu/drm/i915/i915_vma.c > +++ b/drivers/gpu/drm/i915/i915_vma.c > @@ -1637,10 +1637,10 @@ static void force_unbind(struct i915_vma *vma) > GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); > } > > -static void release_references(struct i915_vma *vma, bool vm_ddestroy) > +static void release_references(struct i915_vma *vma, struct intel_gt *gt, > + bool vm_ddestroy) > { > struct drm_i915_gem_object *obj = vma->obj; > - struct intel_gt *gt = vma->vm->gt; > > GEM_BUG_ON(i915_vma_is_active(vma)); > > @@ -1695,11 +1695,12 @@ void i915_vma_destroy_locked(struct i915_vma *vma) > > force_unbind(vma); > list_del_init(&vma->vm_link); > - release_references(vma, false); > + release_references(vma, vma->vm->gt, false); > } > > void i915_vma_destroy(struct i915_vma *vma) > { > + struct intel_gt *gt; > bool vm_ddestroy; > > mutex_lock(&vma->vm->mutex); > @@ -1707,8 +1708,11 @@ void i915_vma_destroy(struct i915_vma *vma) > list_del_init(&vma->vm_link); > vm_ddestroy = vma->vm_ddestroy; > vma->vm_ddestroy = false; > + > + /* vma->vm may be freed when releasing vma->vm->mutex. */ > + gt = vma->vm->gt; > mutex_unlock(&vma->vm->mutex); > - release_references(vma, vm_ddestroy); > + release_references(vma, gt, vm_ddestroy); > } > > void i915_vma_parked(struct intel_gt *gt)
On 20.06.2022 14:36, Thomas Hellström wrote: > 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: e1a7ab4fca ("drm/i915: Remove the vm open count") > > Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > Cc: Matthew Auld <matthew.auld@intel.com> > Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_vma.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c > index 0bffb70b3c5f..04d12f278f57 100644 > --- a/drivers/gpu/drm/i915/i915_vma.c > +++ b/drivers/gpu/drm/i915/i915_vma.c > @@ -1637,10 +1637,10 @@ static void force_unbind(struct i915_vma *vma) > GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); > } > > -static void release_references(struct i915_vma *vma, bool vm_ddestroy) > +static void release_references(struct i915_vma *vma, struct intel_gt *gt, > + bool vm_ddestroy) > { > struct drm_i915_gem_object *obj = vma->obj; > - struct intel_gt *gt = vma->vm->gt; > > GEM_BUG_ON(i915_vma_is_active(vma)); > > @@ -1695,11 +1695,12 @@ void i915_vma_destroy_locked(struct i915_vma *vma) > > force_unbind(vma); > list_del_init(&vma->vm_link); > - release_references(vma, false); > + release_references(vma, vma->vm->gt, false); > } > > void i915_vma_destroy(struct i915_vma *vma) > { > + struct intel_gt *gt; > bool vm_ddestroy; > > mutex_lock(&vma->vm->mutex); > @@ -1707,8 +1708,11 @@ void i915_vma_destroy(struct i915_vma *vma) > list_del_init(&vma->vm_link); > vm_ddestroy = vma->vm_ddestroy; > vma->vm_ddestroy = false; > + > + /* vma->vm may be freed when releasing vma->vm->mutex. */ > + gt = vma->vm->gt; > mutex_unlock(&vma->vm->mutex); > - release_references(vma, vm_ddestroy); > + release_references(vma, gt, vm_ddestroy); Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com> Regards Andrzej > } > > void i915_vma_parked(struct intel_gt *gt)
On Mon, 20 Jun 2022 at 13:37, Thomas Hellström <thomas.hellstrom@linux.intel.com> wrote: > > 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: e1a7ab4fca ("drm/i915: Remove the vm open count") > > Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> > Cc: Matthew Auld <matthew.auld@intel.com> > Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 0bffb70b3c5f..04d12f278f57 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -1637,10 +1637,10 @@ static void force_unbind(struct i915_vma *vma) GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); } -static void release_references(struct i915_vma *vma, bool vm_ddestroy) +static void release_references(struct i915_vma *vma, struct intel_gt *gt, + bool vm_ddestroy) { struct drm_i915_gem_object *obj = vma->obj; - struct intel_gt *gt = vma->vm->gt; GEM_BUG_ON(i915_vma_is_active(vma)); @@ -1695,11 +1695,12 @@ void i915_vma_destroy_locked(struct i915_vma *vma) force_unbind(vma); list_del_init(&vma->vm_link); - release_references(vma, false); + release_references(vma, vma->vm->gt, false); } void i915_vma_destroy(struct i915_vma *vma) { + struct intel_gt *gt; bool vm_ddestroy; mutex_lock(&vma->vm->mutex); @@ -1707,8 +1708,11 @@ void i915_vma_destroy(struct i915_vma *vma) list_del_init(&vma->vm_link); vm_ddestroy = vma->vm_ddestroy; vma->vm_ddestroy = false; + + /* vma->vm may be freed when releasing vma->vm->mutex. */ + gt = vma->vm->gt; mutex_unlock(&vma->vm->mutex); - release_references(vma, vm_ddestroy); + release_references(vma, gt, vm_ddestroy); } void i915_vma_parked(struct intel_gt *gt)
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: e1a7ab4fca ("drm/i915: Remove the vm open count") Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> --- drivers/gpu/drm/i915/i915_vma.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)