public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: John Stultz <john.stultz@linaro.org>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Todd Poynor <toddpoynor@google.com>,
	Greg KH <gregkh@linuxfoundation.org>,
	Colin Cross <ccross@android.com>,
	Android Kernel Team <kernel-team@android.com>,
	John Stultz <john.stultz@linaro.org>
Subject: [PATCH 08/16] staging: ashmem: Avoid deadlock between read and mmap calls
Date: Mon,  3 Feb 2014 10:16:20 -0800	[thread overview]
Message-ID: <1391451388-23906-9-git-send-email-john.stultz@linaro.org> (raw)
In-Reply-To: <1391451388-23906-1-git-send-email-john.stultz@linaro.org>

From: Todd Poynor <toddpoynor@google.com>

Avoid holding ashmem_mutex across code that can page fault.  Page faults
grab the mmap_sem for the process, which are also held by mmap calls
prior to calling ashmem_mmap, which locks ashmem_mutex.  The reversed
order of locking between the two can deadlock.

The calls that can page fault are read() and the ASHMEM_SET_NAME and
ASHMEM_GET_NAME ioctls.  Move the code that accesses userspace pages
outside the ashmem_mutex.

Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Colin Cross <ccross@android.com>
Cc: Android Kernel Team <kernel-team@android.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
[jstultz: minor commit message tweaks]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/staging/android/ashmem.c | 45 +++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 23948f1..713a972 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -295,21 +295,29 @@ static ssize_t ashmem_read(struct file *file, char __user *buf,
 
 	/* If size is not set, or set to 0, always return EOF. */
 	if (asma->size == 0)
-		goto out;
+		goto out_unlock;
 
 	if (!asma->file) {
 		ret = -EBADF;
-		goto out;
+		goto out_unlock;
 	}
 
-	ret = asma->file->f_op->read(asma->file, buf, len, pos);
-	if (ret < 0)
-		goto out;
+	mutex_unlock(&ashmem_mutex);
 
-	/** Update backing file pos, since f_ops->read() doesn't */
-	asma->file->f_pos = *pos;
+	/*
+	 * asma and asma->file are used outside the lock here.  We assume
+	 * once asma->file is set it will never be changed, and will not
+	 * be destroyed until all references to the file are dropped and
+	 * ashmem_release is called.
+	 */
+	ret = asma->file->f_op->read(asma->file, buf, len, pos);
+	if (ret >= 0) {
+		/** Update backing file pos, since f_ops->read() doesn't */
+		asma->file->f_pos = *pos;
+	}
+	return ret;
 
-out:
+out_unlock:
 	mutex_unlock(&ashmem_mutex);
 	return ret;
 }
@@ -498,6 +506,7 @@ out:
 
 static int set_name(struct ashmem_area *asma, void __user *name)
 {
+	int len;
 	int ret = 0;
 	char local_name[ASHMEM_NAME_LEN];
 
@@ -510,21 +519,19 @@ static int set_name(struct ashmem_area *asma, void __user *name)
 	 * variable that does not need protection and later copy the local
 	 * variable to the structure member with lock held.
 	 */
-	if (copy_from_user(local_name, name, ASHMEM_NAME_LEN))
-		return -EFAULT;
-
+	len = strncpy_from_user(local_name, name, ASHMEM_NAME_LEN);
+	if (len < 0)
+		return len;
+	if (len == ASHMEM_NAME_LEN)
+		local_name[ASHMEM_NAME_LEN - 1] = '\0';
 	mutex_lock(&ashmem_mutex);
 	/* cannot change an existing mapping's name */
-	if (unlikely(asma->file)) {
+	if (unlikely(asma->file))
 		ret = -EINVAL;
-		goto out;
-	}
-	memcpy(asma->name + ASHMEM_NAME_PREFIX_LEN,
-		local_name, ASHMEM_NAME_LEN);
-	asma->name[ASHMEM_FULL_NAME_LEN-1] = '\0';
-out:
-	mutex_unlock(&ashmem_mutex);
+	else
+		strcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name);
 
+	mutex_unlock(&ashmem_mutex);
 	return ret;
 }
 
-- 
1.8.3.2


  parent reply	other threads:[~2014-02-03 18:16 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-03 18:16 [PATCH 00/16] [RFC] Staging updates from the Android tree John Stultz
2014-02-03 18:16 ` [PATCH 01/16] staging: android: Split uapi out of android_alarm.h John Stultz
2014-02-03 18:16 ` [PATCH 02/16] staging: android: Split uapi out of ashmem.h John Stultz
2014-02-03 18:16 ` [PATCH 03/16] staging: android: split uapi out of sync.h and sw_sync.h John Stultz
2014-02-03 18:16 ` [PATCH 04/16] staging: android: Split uapi out of binder.h John Stultz
2014-02-03 18:16 ` [PATCH 05/16] staging: sw_sync: Add stubs for kernels without CONFIG_SW_SYNC John Stultz
2014-02-03 18:16 ` [PATCH 06/16] staging: sync: Signal pt before sync_timeline object gets destroyed John Stultz
2014-02-03 18:16 ` [PATCH 07/16] staging: sync: Fix a race condition between release_obj and print_obj John Stultz
2014-02-03 18:16 ` John Stultz [this message]
2014-02-03 18:16 ` [PATCH 09/16] staging: ion: Create separate heap and client debugfs directories John Stultz
2014-02-03 18:16 ` [PATCH 10/16] staging: ion: Fix debugfs handling of multiple kernel clients John Stultz
2014-02-03 18:16 ` [PATCH 11/16] staging: ion: Store a copy of the client name on client creation John Stultz
2014-02-03 18:16 ` [PATCH 12/16] staging: ion: Make sure all clients are exposed in debugfs John Stultz
2014-02-03 18:16 ` [PATCH 13/16] staging: ion: Fix overflow and list bugs in system heap John Stultz
2014-02-03 18:16 ` [PATCH 14/16] staging: ion: Fix ION_IOC_FREE compat ioctl John Stultz
2014-02-03 18:16 ` [PATCH 15/16] staging: ion: Move shrinker out of heaps John Stultz
2014-02-03 18:16 ` [PATCH 16/16] staging: ion: Add private buffer flag to skip page pooling on free John Stultz
2014-02-04  2:06 ` [PATCH 00/16] [RFC] Staging updates from the Android tree Greg KH
2014-02-04 20:14   ` John Stultz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1391451388-23906-9-git-send-email-john.stultz@linaro.org \
    --to=john.stultz@linaro.org \
    --cc=ccross@android.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=toddpoynor@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox