source:
trunk/server/common/patches/cve-2014-3153-1.patch
@
2557
Last change on this file since 2557 was 2557, checked in by achernya, 10 years ago | |
---|---|
File size: 2.6 KB |
-
kernel/futex.c
From b58623fb64ff0454ec20bce7a02275a20c23086d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner <tglx@linutronix.de> Date: Tue, 3 Jun 2014 12:27:06 +0000 Subject: [PATCH 1/4] futex-prevent-requeue-pi-on-same-futex.patch futex: Forbid uaddr == uaddr2 in futex_requeue(..., requeue_pi=1) commit e9c243a5a6de0be8e584c604d353412584b592f8 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, then dangling pointers may be left for rt_waiter resulting in an exploitable condition. This change brings futex_requeue() in line with futex_wait_requeue_pi() which performs the same check as per commit 6f7b0a2a5c0f ("futex: Forbid uaddr == uaddr2 in futex_wait_requeue_pi()") [ tglx: Compare the resulting keys as well, as uaddrs might be different depending on the mapping ] Fixes CVE-2014-3153. Reported-by: Pinkie Pie Signed-off-by: Will Drewry <wad@chromium.org> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Darren Hart <dvhart@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- kernel/futex.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/kernel/futex.c b/kernel/futex.c index 58743c0..93e522f 100644
a b static int futex_requeue(u32 __user *uaddr1, unsigned int flags, 1293 1293 1294 1294 if (requeue_pi) { 1295 1295 /* 1296 * Requeue PI only works on two distinct uaddrs. This 1297 * check is only valid for private futexes. See below. 1298 */ 1299 if (uaddr1 == uaddr2) 1300 return -EINVAL; 1301 1302 /* 1296 1303 * requeue_pi requires a pi_state, try to allocate it now 1297 1304 * without any locks in case it fails. 1298 1305 */ … … retry: 1330 1337 if (unlikely(ret != 0)) 1331 1338 goto out_put_key1; 1332 1339 1340 /* 1341 * The check above which compares uaddrs is not sufficient for 1342 * shared futexes. We need to compare the keys: 1343 */ 1344 if (requeue_pi && match_futex(&key1, &key2)) { 1345 ret = -EINVAL; 1346 goto out_put_keys; 1347 } 1348 1333 1349 hb1 = hash_futex(&key1); 1334 1350 hb2 = hash_futex(&key2); 1335 1351 … … static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, 2360 2376 if (ret) 2361 2377 goto out_key2; 2362 2378 2379 /* 2380 * The check above which compares uaddrs is not sufficient for 2381 * shared futexes. We need to compare the keys: 2382 */ 2383 if (match_futex(&q.key, &key2)) { 2384 ret = -EINVAL; 2385 goto out_put_keys; 2386 } 2387 2363 2388 /* Queue the futex_q, drop the hb lock, wait for wakeup. */ 2364 2389 futex_wait_queue_me(hb, &q, to); 2365 2390
Note: See TracBrowser
for help on using the repository browser.