Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1481466 > unrolled thread

[PATCH 4.7 21/59] drm/msm: fix use of copy_from_user() while holding spinlock

Started byGreg Kroah-Hartman <gregkh@linuxfoundation.org>
First post2016-09-12 17:40 +0200
Last post2016-09-12 17:40 +0200
Articles 1 — 1 participant

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 4.7 21/59] drm/msm: fix use of copy_from_user() while holding spinlock Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-09-12 17:40 +0200

#1481466 — [PATCH 4.7 21/59] drm/msm: fix use of copy_from_user() while holding spinlock

FromGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Date2016-09-12 17:40 +0200
Subject[PATCH 4.7 21/59] drm/msm: fix use of copy_from_user() while holding spinlock
Message-ID<sgBuX-58A-79@gated-at.bofh.it>
4.7-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Rob Clark <robdclark@gmail.com>

commit 89f82cbb0d5c0ab768c8d02914188aa2211cd2e3 upstream.

Use instead __copy_from_user_inatomic() and fallback to slow-path where
we drop and re-aquire the lock in case of fault.

Reported-by: Vaishali Thakkar <vaishali.thakkar@oracle.com>
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/gpu/drm/msm/msm_gem_submit.c |   27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -62,6 +62,14 @@ void msm_gem_submit_free(struct msm_gem_
 	kfree(submit);
 }
 
+static inline unsigned long __must_check
+copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_from_user_inatomic(to, from, n);
+	return -EFAULT;
+}
+
 static int submit_lookup_objects(struct msm_gem_submit *submit,
 		struct drm_msm_gem_submit *args, struct drm_file *file)
 {
@@ -69,6 +77,7 @@ static int submit_lookup_objects(struct
 	int ret = 0;
 
 	spin_lock(&file->table_lock);
+	pagefault_disable();
 
 	for (i = 0; i < args->nr_bos; i++) {
 		struct drm_msm_gem_submit_bo submit_bo;
@@ -82,10 +91,15 @@ static int submit_lookup_objects(struct
 		 */
 		submit->bos[i].flags = 0;
 
-		ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
-		if (ret) {
-			ret = -EFAULT;
-			goto out_unlock;
+		ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo));
+		if (unlikely(ret)) {
+			pagefault_enable();
+			spin_unlock(&file->table_lock);
+			ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+			if (ret)
+				goto out;
+			spin_lock(&file->table_lock);
+			pagefault_disable();
 		}
 
 		if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) {
@@ -125,9 +139,12 @@ static int submit_lookup_objects(struct
 	}
 
 out_unlock:
-	submit->nr_bos = i;
+	pagefault_enable();
 	spin_unlock(&file->table_lock);
 
+out:
+	submit->nr_bos = i;
+
 	return ret;
 }
 

[toc] | [standalone]


Back to top | Article view | linux.kernel


csiph-web