aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-12-12 12:53:51 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-17 22:46:06 -0400
commit6f725d97db3ad8763c086f85ceb20938e99ee351 (patch)
tree253b47f2b30a34ea246e17b1435baf4f0142812d
parentbff0667f0f1778e792989baa453c4e70d434b26b (diff)
futex: move user address verification up to common code
When debugging the read-only hugepage case, I was confused by the fact that get_futex_key() did an access_ok() only for the non-shared futex case, since the user address checking really isn't in any way specific to the private key handling. Now, it turns out that the shared key handling does effectively do the equivalent checks inside get_user_pages_fast() (it doesn't actually check the address range on x86, but does check the page protections for being a user page). So it wasn't actually a bug, but the fact that we treat the address differently for private and shared futexes threw me for a loop. Just move the check up, so that it gets done for both cases. Also, use the 'rw' parameter for the type, even if it doesn't actually matter any more (it's a historical artifact of the old racy i386 "page faults from kernel space don't check write protections"). Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/futex.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index a283b3041072..dac8f4c5e020 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -250,6 +250,9 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
250 return -EINVAL; 250 return -EINVAL;
251 address -= key->both.offset; 251 address -= key->both.offset;
252 252
253 if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
254 return -EFAULT;
255
253 /* 256 /*
254 * PROCESS_PRIVATE futexes are fast. 257 * PROCESS_PRIVATE futexes are fast.
255 * As the mm cannot disappear under us and the 'key' only needs 258 * As the mm cannot disappear under us and the 'key' only needs
@@ -258,8 +261,6 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
258 * but access_ok() should be faster than find_vma() 261 * but access_ok() should be faster than find_vma()
259 */ 262 */
260 if (!fshared) { 263 if (!fshared) {
261 if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
262 return -EFAULT;
263 key->private.mm = mm; 264 key->private.mm = mm;
264 key->private.address = address; 265 key->private.address = address;
265 get_futex_key_refs(key); 266 get_futex_key_refs(key);