Skip to content

Commit 6f7b0a2

Browse files
dvhartKAGA-KOKO
authored andcommitted
futex: Forbid uaddr == uaddr2 in futex_wait_requeue_pi()
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 <[email protected]> Cc: Dave Jones <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/ad82bfe7f7d130247fbe2b5b4275654807774227.1342809673.git.dvhart@linux.intel.com Signed-off-by: Thomas Gleixner <[email protected]>
1 parent f27071c commit 6f7b0a2

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

kernel/futex.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
22312231
* @uaddr2: the pi futex we will take prior to returning to user-space
22322232
*
22332233
* 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
2235-
* complete the acquisition of the rt_mutex prior to returning to userspace.
2236-
* This ensures the rt_mutex maintains an owner when it has waiters; without
2237-
* one, the pi logic wouldn't know which task to boost/deboost, if there was a
2238-
* need to.
2234+
* uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake
2235+
* on uaddr2 and complete the acquisition of the rt_mutex prior to returning to
2236+
* userspace. This ensures the rt_mutex maintains an owner when it has waiters;
2237+
* without one, the pi logic would not know which task to boost/deboost, if
2238+
* there was a need to.
22392239
*
22402240
* We call schedule in futex_wait_queue_me() when we enqueue and return there
22412241
* via the following:
@@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
22722272
struct futex_q q = futex_q_init;
22732273
int res, ret;
22742274

2275+
if (uaddr == uaddr2)
2276+
return -EINVAL;
2277+
22752278
if (!bitset)
22762279
return -EINVAL;
22772280

0 commit comments

Comments
 (0)