This is a note to let you know that I've just added the patch titled
drm/i915: Prevent use-after-free in invalidate_range_start callback
to the 3.19-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-i915-prevent-use-after-free-in-invalidate_range_start-callback.patch
and it can be found in the queue-3.19 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.
>From 460822b0b1a77db859b0320469799fa4dbe4d367 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Winiarski?= <[email protected]>
Date: Tue, 3 Feb 2015 15:48:17 +0100
Subject: drm/i915: Prevent use-after-free in invalidate_range_start callback
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: =?UTF-8?q?Micha=C5=82=20Winiarski?= <[email protected]>
commit 460822b0b1a77db859b0320469799fa4dbe4d367 upstream.
It's possible for invalidate_range_start mmu notifier callback to race
against userptr object release. If the gem object was released prior to
obtaining the spinlock in invalidate_range_start we're hitting null
pointer dereference.
Testcase: igt/gem_userptr_blits/stress-mm-invalidate-close
Testcase: igt/gem_userptr_blits/stress-mm-invalidate-close-overlap
Cc: Chris Wilson <[email protected]>
Signed-off-by: MichaĆ Winiarski <[email protected]>
Reviewed-by: Chris Wilson <[email protected]>
[Jani: added code comment suggested by Chris]
Signed-off-by: Jani Nikula <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/gpu/drm/i915/i915_gem_userptr.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -113,7 +113,10 @@ restart:
continue;
obj = mo->obj;
- drm_gem_object_reference(&obj->base);
+
+ if (!kref_get_unless_zero(&obj->base.refcount))
+ continue;
+
spin_unlock(&mn->lock);
cancel_userptr(obj);
@@ -149,7 +152,20 @@ static void i915_gem_userptr_mn_invalida
it = interval_tree_iter_first(&mn->objects, start, end);
if (it != NULL) {
obj = container_of(it, struct i915_mmu_object, it)->obj;
- drm_gem_object_reference(&obj->base);
+
+ /* The mmu_object is released late when destroying the
+ * GEM object so it is entirely possible to gain a
+ * reference on an object in the process of being freed
+ * since our serialisation is via the spinlock and not
+ * the struct_mutex - and consequently use it after it
+ * is freed and then double free it.
+ */
+ if (!kref_get_unless_zero(&obj->base.refcount)) {
+ spin_unlock(&mn->lock);
+ serial = 0;
+ continue;
+ }
+
serial = mn->serial;
}
spin_unlock(&mn->lock);
Patches currently in stable-queue which might be from
[email protected] are
queue-3.19/drm-i915-prevent-use-after-free-in-invalidate_range_start-callback.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html