diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-03 14:00:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-03 14:00:26 -0400 |
commit | c4e62d67854e247b09ffe763163057237c8b1614 (patch) | |
tree | ddcdca15427671ab44334320e91b67877aa95f1a /kernel | |
parent | 1ca0049f2c8b28611f30798aa75858763c9fcbea (diff) | |
parent | 6f7b0a2a5c0fb03be7c25bd1745baa50582348ef (diff) |
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull futex fixes from Ingo Molnar:
"A couple of futex fixes from Darren Hart: two bugs reported by Dave
Jones (found with his trinity test) and Dan Carpenter through static
analysis. The third found while debugging the first two."
* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
futex: Forbid uaddr == uaddr2 in futex_wait_requeue_pi()
futex: Fix bug in WARN_ON for NULL q.pi_state
futex: Test for pi_mutex on fault in futex_wait_requeue_pi()
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/futex.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index e2b0fb9a0b3b..3717e7b306e0 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, | |||
2231 | * @uaddr2: the pi futex we will take prior to returning to user-space | 2231 | * @uaddr2: the pi futex we will take prior to returning to user-space |
2232 | * | 2232 | * |
2233 | * The caller will wait on uaddr and will be requeued by futex_requeue() to | 2233 | * The caller will wait on uaddr and will be requeued by futex_requeue() to |
2234 | * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and | 2234 | * uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake |
2235 | * complete the acquisition of the rt_mutex prior to returning to userspace. | 2235 | * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to |
2236 | * This ensures the rt_mutex maintains an owner when it has waiters; without | 2236 | * userspace. This ensures the rt_mutex maintains an owner when it has waiters; |
2237 | * one, the pi logic wouldn't know which task to boost/deboost, if there was a | 2237 | * without one, the pi logic would not know which task to boost/deboost, if |
2238 | * need to. | 2238 | * there was a need to. |
2239 | * | 2239 | * |
2240 | * We call schedule in futex_wait_queue_me() when we enqueue and return there | 2240 | * We call schedule in futex_wait_queue_me() when we enqueue and return there |
2241 | * via the following: | 2241 | * via the following: |
@@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2272 | struct futex_q q = futex_q_init; | 2272 | struct futex_q q = futex_q_init; |
2273 | int res, ret; | 2273 | int res, ret; |
2274 | 2274 | ||
2275 | if (uaddr == uaddr2) | ||
2276 | return -EINVAL; | ||
2277 | |||
2275 | if (!bitset) | 2278 | if (!bitset) |
2276 | return -EINVAL; | 2279 | return -EINVAL; |
2277 | 2280 | ||
@@ -2343,7 +2346,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2343 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor | 2346 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor |
2344 | * the pi_state. | 2347 | * the pi_state. |
2345 | */ | 2348 | */ |
2346 | WARN_ON(!&q.pi_state); | 2349 | WARN_ON(!q.pi_state); |
2347 | pi_mutex = &q.pi_state->pi_mutex; | 2350 | pi_mutex = &q.pi_state->pi_mutex; |
2348 | ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); | 2351 | ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); |
2349 | debug_rt_mutex_free_waiter(&rt_waiter); | 2352 | debug_rt_mutex_free_waiter(&rt_waiter); |
@@ -2370,7 +2373,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2370 | * fault, unlock the rt_mutex and return the fault to userspace. | 2373 | * fault, unlock the rt_mutex and return the fault to userspace. |
2371 | */ | 2374 | */ |
2372 | if (ret == -EFAULT) { | 2375 | if (ret == -EFAULT) { |
2373 | if (rt_mutex_owner(pi_mutex) == current) | 2376 | if (pi_mutex && rt_mutex_owner(pi_mutex) == current) |
2374 | rt_mutex_unlock(pi_mutex); | 2377 | rt_mutex_unlock(pi_mutex); |
2375 | } else if (ret == -EINTR) { | 2378 | } else if (ret == -EINTR) { |
2376 | /* | 2379 | /* |