Thomas Zimmermann 161476
From 8244a3bc27b3efd057da154b8d7e414670d5044f Mon Sep 17 00:00:00 2001
Thomas Zimmermann 161476
From: Anand K Mistry <amistry@google.com>
Thomas Zimmermann 161476
Date: Thu, 30 Sep 2021 09:00:07 +1000
Thomas Zimmermann 161476
Subject: drm/prime: Fix use after free in mmap with drm_gem_ttm_mmap
Thomas Zimmermann 161476
Git-commit: 8244a3bc27b3efd057da154b8d7e414670d5044f
Thomas Zimmermann 161476
Patch-mainline: v5.16-rc1
Thomas Zimmermann 161476
References: bsc#1152472
Thomas Zimmermann 161476
Thomas Zimmermann 161476
drm_gem_ttm_mmap() drops a reference to the gem object on success. If
Thomas Zimmermann 161476
the gem object's refcount == 1 on entry to drm_gem_prime_mmap(), that
Thomas Zimmermann 161476
drop will free the gem object, and the subsequent drm_gem_object_get()
Thomas Zimmermann 161476
will be a UAF. Fix by grabbing a reference before calling the mmap
Thomas Zimmermann 161476
helper.
Thomas Zimmermann 161476
Thomas Zimmermann 161476
This issue was forseen when the reference dropping was adding in
Thomas Zimmermann 161476
commit 9786b65bc61ac ("drm/ttm: fix mmap refcounting"):
Thomas Zimmermann 161476
  "For that to work properly the drm_gem_object_get() call in
Thomas Zimmermann 161476
  drm_gem_ttm_mmap() must be moved so it happens before calling
Thomas Zimmermann 161476
  obj->funcs->mmap(), otherwise the gem refcount would go down
Thomas Zimmermann 161476
  to zero."
Thomas Zimmermann 161476
Thomas Zimmermann 161476
Signed-off-by: Anand K Mistry <amistry@google.com>
Thomas Zimmermann 161476
Fixes: 9786b65bc61a ("drm/ttm: fix mmap refcounting")
Thomas Zimmermann 161476
Cc: Gerd Hoffmann <kraxel@redhat.com>
Thomas Zimmermann 161476
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Thomas Zimmermann 161476
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Thomas Zimmermann 161476
Cc: Maxime Ripard <mripard@kernel.org>
Thomas Zimmermann 161476
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Thomas Zimmermann 161476
Cc: David Airlie <airlied@linux.ie>
Thomas Zimmermann 161476
Cc: Daniel Vetter <daniel@ffwll.ch>
Thomas Zimmermann 161476
Cc: dri-devel@lists.freedesktop.org
Thomas Zimmermann 161476
Cc: <stable@vger.kernel.org> # v5.5+
Thomas Zimmermann 161476
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Thomas Zimmermann 161476
Link: https://patchwork.freedesktop.org/patch/msgid/20210930085932.1.I8043d61cc238e0168e2f4ca5f4783223434aa587@changeid
Thomas Zimmermann 161476
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Thomas Zimmermann 161476
---
Thomas Zimmermann 161476
 drivers/gpu/drm/drm_prime.c |    8 +++++---
Thomas Zimmermann 161476
 1 file changed, 5 insertions(+), 3 deletions(-)
Thomas Zimmermann 161476
Thomas Zimmermann 161476
--- a/drivers/gpu/drm/drm_prime.c
Thomas Zimmermann 161476
+++ b/drivers/gpu/drm/drm_prime.c
Thomas Zimmermann 161476
@@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_ob
Thomas Zimmermann 161476
 	vma->vm_pgoff += drm_vma_node_start(&obj->vma_node);
Thomas Zimmermann 161476
 
Thomas Zimmermann 161476
 	if (obj->funcs && obj->funcs->mmap) {
Thomas Zimmermann 161476
+		drm_gem_object_get(obj);
Thomas Zimmermann 161476
 		ret = obj->funcs->mmap(obj, vma);
Thomas Zimmermann 161476
-		if (ret)
Thomas Zimmermann 161476
-			return ret;
Thomas Zimmermann 161476
+		if (ret) {
Thomas Zimmermann 161476
+			drm_gem_object_put(obj);
Thomas Zimmermann 161476
+ 			return ret;
Thomas Zimmermann 161476
+		}
Thomas Zimmermann 161476
 		vma->vm_private_data = obj;
Thomas Zimmermann 161476
-		drm_gem_object_get(obj);
Thomas Zimmermann 161476
 		return 0;
Thomas Zimmermann 161476
 	}
Thomas Zimmermann 161476