| From e8436c7d6f2603d6c617d49d09fa11ab334e94a2 Mon Sep 17 00:00:00 2001 |
| From: Darren Hart <dvhart@linux.intel.com> |
| Date: Fri, 20 Jul 2012 11:53:31 -0700 |
| Subject: [PATCH] futex: Forbid uaddr == uaddr2 in futex_wait_requeue_pi() |
| |
| commit 6f7b0a2a5c0fb03be7c25bd1745baa50582348ef upstream. |
| |
| If uaddr == uaddr2, then we have broken the rule of only requeueing |
| from a non-pi futex to a pi futex with this call. If we attempt this, |
| as the trinity test suite manages to do, we miss early wakeups as |
| q.key is equal to key2 (because they are the same uaddr). We will then |
| attempt to dereference the pi_mutex (which would exist had the futex_q |
| been properly requeued to a pi futex) and trigger a NULL pointer |
| dereference. |
| |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| Cc: Dave Jones <davej@redhat.com> |
| Link: http://lkml.kernel.org/r/ad82bfe7f7d130247fbe2b5b4275654807774227.1342809673.git.dvhart@linux.intel.com |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| kernel/futex.c | 13 ++++++++----- |
| 1 file changed, 8 insertions(+), 5 deletions(-) |
| |
| diff --git a/kernel/futex.c b/kernel/futex.c |
| index 8b467b4a437f..4a8f72850152 100644 |
| --- a/kernel/futex.c |
| +++ b/kernel/futex.c |
| @@ -2204,11 +2204,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, |
| * @uaddr2: the pi futex we will take prior to returning to user-space |
| * |
| * The caller will wait on uaddr and will be requeued by futex_requeue() to |
| - * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and |
| - * complete the acquisition of the rt_mutex prior to returning to userspace. |
| - * This ensures the rt_mutex maintains an owner when it has waiters; without |
| - * one, the pi logic wouldn't know which task to boost/deboost, if there was a |
| - * need to. |
| + * uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake |
| + * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to |
| + * userspace. This ensures the rt_mutex maintains an owner when it has waiters; |
| + * without one, the pi logic would not know which task to boost/deboost, if |
| + * there was a need to. |
| * |
| * We call schedule in futex_wait_queue_me() when we enqueue and return there |
| * via the following: |
| @@ -2245,6 +2245,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, |
| struct futex_q q; |
| int res, ret; |
| |
| + if (uaddr == uaddr2) |
| + return -EINVAL; |
| + |
| if (!bitset) |
| return -EINVAL; |
| |
| -- |
| 1.8.5.2 |
| |