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
next prev 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