Author: caster Date: 2014-06-05 22:20:47 +0000 (Thu, 05 Jun 2014) New Revision: 2806
Added: genpatches-2.6/trunk/3.12/1501-futex-add-another-early-deadlock-detection-check.patch genpatches-2.6/trunk/3.12/1502-futex-prevent-attaching-to-kernel-threads.patch genpatches-2.6/trunk/3.12/1503-futex-prevent-requeue-pi-on-same-futex-patch-futex-forbid-uaddr-uaddr2-in-futex_requeue-requeue_pi-1.patch genpatches-2.6/trunk/3.12/1504-futex-validate-atomic-acquisition-in-futex_lock_pi_atomic.patch genpatches-2.6/trunk/3.12/1505-futex-always-cleanup-owner-tid-in-unlock_pi.patch genpatches-2.6/trunk/3.12/1506-futex-make-lookup_pi_state-more-robust.patch Modified: genpatches-2.6/trunk/3.12/0000_README Log: CVE-2014-3153 Modified: genpatches-2.6/trunk/3.12/0000_README =================================================================== --- genpatches-2.6/trunk/3.12/0000_README 2014-06-03 22:10:40 UTC (rev 2805) +++ genpatches-2.6/trunk/3.12/0000_README 2014-06-05 22:20:47 UTC (rev 2806) @@ -134,6 +134,30 @@ From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a96e15096da6e7491107321cfa660c7c2aa119d Desc: selinux: add SOCK_DIAG_BY_FAMILY to the list of netlink message types +Patch: 1501-futex-add-another-early-deadlock-detection-check.patch +From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=866293ee54227584ffcb4a42f69c1f365974ba7f +Desc: CVE-2014-3153 + +Patch: 1502-futex-prevent-attaching-to-kernel-threads.patch +From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f0d71b3dcb8332f7971b5f2363632573e6d9486a +Desc: CVE-2014-3153 + +Patch: 1503-futex-prevent-requeue-pi-on-same-futex-patch-futex-forbid-uaddr-uaddr2-in-futex_requeue-requeue_pi-1.patch +From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=e9c243a5a6de0be8e584c604d353412584b592f8 +Desc: CVE-2014-3153 + +Patch: 1504-futex-validate-atomic-acquisition-in-futex_lock_pi_atomic.patch +From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=b3eaa9fc5cd0a4d74b18f6b8dc617aeaf1873270 +Desc: CVE-2014-3153 + +Patch: 1505-futex-always-cleanup-owner-tid-in-unlock_pi.patch +From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=13fbca4c6ecd96ec1a1cfa2e4f2ce191fe928a5e +Desc: CVE-2014-3153 + +Patch: 1506-futex-make-lookup_pi_state-more-robust.patch +From: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54a217887a7b658e2650c3feff22756ab80c7339 +Desc: CVE-2014-3153 + Patch: 1700_enable-thinkpad-micled.patch From: https://bugs.gentoo.org/show_bug.cgi?id=449248 Desc: Enable mic mute led in thinkpads Added: genpatches-2.6/trunk/3.12/1501-futex-add-another-early-deadlock-detection-check.patch =================================================================== --- genpatches-2.6/trunk/3.12/1501-futex-add-another-early-deadlock-detection-check.patch (rev 0) +++ genpatches-2.6/trunk/3.12/1501-futex-add-another-early-deadlock-detection-check.patch 2014-06-05 22:20:47 UTC (rev 2806) @@ -0,0 +1,160 @@ +From: Thomas Gleixner <t...@linutronix.de> +Date: Mon, 12 May 2014 20:45:34 +0000 +Subject: futex: Add another early deadlock detection check +Git-commit: 866293ee54227584ffcb4a42f69c1f365974ba7f + +Dave Jones trinity syscall fuzzer exposed an issue in the deadlock +detection code of rtmutex: + http://lkml.kernel.org/r/20140429151655.ga14...@redhat.com + +That underlying issue has been fixed with a patch to the rtmutex code, +but the futex code must not call into rtmutex in that case because + - it can detect that issue early + - it avoids a different and more complex fixup for backing out + +If the user space variable got manipulated to 0x80000000 which means +no lock holder, but the waiters bit set and an active pi_state in the +kernel is found we can figure out the recursive locking issue by +looking at the pi_state owner. If that is the current task, then we +can safely return -EDEADLK. + +The check should have been added in commit 59fa62451 (futex: Handle +futex_pi OWNER_DIED take over correctly) already, but I did not see +the above issue caused by user space manipulation back then. + +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Cc: Dave Jones <da...@redhat.com> +Cc: Linus Torvalds <torva...@linux-foundation.org> +Cc: Peter Zijlstra <pet...@infradead.org> +Cc: Darren Hart <dar...@dvhart.com> +Cc: Davidlohr Bueso <davidl...@hp.com> +Cc: Steven Rostedt <rost...@goodmis.org> +Cc: Clark Williams <willi...@redhat.com> +Cc: Paul McKenney <paul...@linux.vnet.ibm.com> +Cc: Lai Jiangshan <la...@cn.fujitsu.com> +Cc: Roland McGrath <rol...@hack.frob.com> +Cc: Carlos ODonell <car...@redhat.com> +Cc: Jakub Jelinek <ja...@redhat.com> +Cc: Michael Kerrisk <mtk.manpa...@gmail.com> +Cc: Sebastian Andrzej Siewior <bige...@linutronix.de> +Link: http://lkml.kernel.org/r/20140512201701.097349...@linutronix.de +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Cc: sta...@vger.kernel.org +--- + kernel/futex.c | 47 ++++++++++++++++++++++++++++++++++------------- + 1 file changed, 34 insertions(+), 13 deletions(-) + +Index: linux-3.12/kernel/futex.c +=================================================================== +--- linux-3.12.orig/kernel/futex.c ++++ linux-3.12/kernel/futex.c +@@ -596,7 +596,8 @@ void exit_pi_state_list(struct task_stru + + static int + lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, +- union futex_key *key, struct futex_pi_state **ps) ++ union futex_key *key, struct futex_pi_state **ps, ++ struct task_struct *task) + { + struct futex_pi_state *pi_state = NULL; + struct futex_q *this, *next; +@@ -640,6 +641,16 @@ lookup_pi_state(u32 uval, struct futex_h + return -EINVAL; + } + ++ /* ++ * Protect against a corrupted uval. If uval ++ * is 0x80000000 then pid is 0 and the waiter ++ * bit is set. So the deadlock check in the ++ * calling code has failed and we did not fall ++ * into the check above due to !pid. ++ */ ++ if (task && pi_state->owner == task) ++ return -EDEADLK; ++ + atomic_inc(&pi_state->refcount); + *ps = pi_state; + +@@ -789,7 +800,7 @@ retry: + * We dont have the lock. Look up the PI state (or create it if + * we are the first waiter): + */ +- ret = lookup_pi_state(uval, hb, key, ps); ++ ret = lookup_pi_state(uval, hb, key, ps, task); + + if (unlikely(ret)) { + switch (ret) { +@@ -1199,7 +1210,7 @@ void requeue_pi_wake_futex(struct futex_ + * + * Return: + * 0 - failed to acquire the lock atomically; +- * 1 - acquired the lock; ++ * >0 - acquired the lock, return value is vpid of the top_waiter + * <0 - error + */ + static int futex_proxy_trylock_atomic(u32 __user *pifutex, +@@ -1210,7 +1221,7 @@ static int futex_proxy_trylock_atomic(u3 + { + struct futex_q *top_waiter = NULL; + u32 curval; +- int ret; ++ int ret, vpid; + + if (get_futex_value_locked(&curval, pifutex)) + return -EFAULT; +@@ -1238,11 +1249,13 @@ static int futex_proxy_trylock_atomic(u3 + * the contended case or if set_waiters is 1. The pi_state is returned + * in ps in contended cases. + */ ++ vpid = task_pid_vnr(top_waiter->task); + ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task, + set_waiters); +- if (ret == 1) ++ if (ret == 1) { + requeue_pi_wake_futex(top_waiter, key2, hb2); +- ++ return vpid; ++ } + return ret; + } + +@@ -1274,7 +1287,6 @@ static int futex_requeue(u32 __user *uad + struct futex_hash_bucket *hb1, *hb2; + struct plist_head *head1; + struct futex_q *this, *next; +- u32 curval2; + + if (requeue_pi) { + /* +@@ -1360,16 +1372,25 @@ retry_private: + * At this point the top_waiter has either taken uaddr2 or is + * waiting on it. If the former, then the pi_state will not + * exist yet, look it up one more time to ensure we have a +- * reference to it. ++ * reference to it. If the lock was taken, ret contains the ++ * vpid of the top waiter task. + */ +- if (ret == 1) { ++ if (ret > 0) { + WARN_ON(pi_state); + drop_count++; + task_count++; +- ret = get_futex_value_locked(&curval2, uaddr2); +- if (!ret) +- ret = lookup_pi_state(curval2, hb2, &key2, +- &pi_state); ++ /* ++ * If we acquired the lock, then the user ++ * space value of uaddr2 should be vpid. It ++ * cannot be changed by the top waiter as it ++ * is blocked on hb2 lock if it tries to do ++ * so. If something fiddled with it behind our ++ * back the pi state lookup might unearth ++ * it. So we rather use the known value than ++ * rereading and handing potential crap to ++ * lookup_pi_state. ++ */ ++ ret = lookup_pi_state(ret, hb2, &key2, &pi_state, NULL); + } + + switch (ret) { Added: genpatches-2.6/trunk/3.12/1502-futex-prevent-attaching-to-kernel-threads.patch =================================================================== --- genpatches-2.6/trunk/3.12/1502-futex-prevent-attaching-to-kernel-threads.patch (rev 0) +++ genpatches-2.6/trunk/3.12/1502-futex-prevent-attaching-to-kernel-threads.patch 2014-06-05 22:20:47 UTC (rev 2806) @@ -0,0 +1,52 @@ +From: Thomas Gleixner <t...@linutronix.de> +Date: Mon, 12 May 2014 20:45:35 +0000 +Subject: futex: Prevent attaching to kernel threads +Git-commit: f0d71b3dcb8332f7971b5f2363632573e6d9486a + +We happily allow userspace to declare a random kernel thread to be the +owner of a user space PI futex. + +Found while analysing the fallout of Dave Jones syscall fuzzer. + +We also should validate the thread group for private futexes and find +some fast way to validate whether the "alleged" owner has RW access on +the file which backs the SHM, but that's a separate issue. + +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Cc: Dave Jones <da...@redhat.com> +Cc: Linus Torvalds <torva...@linux-foundation.org> +Cc: Peter Zijlstra <pet...@infradead.org> +Cc: Darren Hart <dar...@dvhart.com> +Cc: Davidlohr Bueso <davidl...@hp.com> +Cc: Steven Rostedt <rost...@goodmis.org> +Cc: Clark Williams <willi...@redhat.com> +Cc: Paul McKenney <paul...@linux.vnet.ibm.com> +Cc: Lai Jiangshan <la...@cn.fujitsu.com> +Cc: Roland McGrath <rol...@hack.frob.com> +Cc: Carlos ODonell <car...@redhat.com> +Cc: Jakub Jelinek <ja...@redhat.com> +Cc: Michael Kerrisk <mtk.manpa...@gmail.com> +Cc: Sebastian Andrzej Siewior <bige...@linutronix.de> +Link: http://lkml.kernel.org/r/20140512201701.194824...@linutronix.de +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Cc: sta...@vger.kernel.org +--- + kernel/futex.c | 5 +++++ + 1 file changed, 5 insertions(+) + +Index: linux-3.12/kernel/futex.c +=================================================================== +--- linux-3.12.orig/kernel/futex.c ++++ linux-3.12/kernel/futex.c +@@ -668,6 +668,11 @@ lookup_pi_state(u32 uval, struct futex_h + if (!p) + return -ESRCH; + ++ if (!p->mm) { ++ put_task_struct(p); ++ return -EPERM; ++ } ++ + /* + * We need to look at the task state flags to figure out, + * whether the task is exiting. To protect against the do_exit Added: genpatches-2.6/trunk/3.12/1503-futex-prevent-requeue-pi-on-same-futex-patch-futex-forbid-uaddr-uaddr2-in-futex_requeue-requeue_pi-1.patch =================================================================== --- genpatches-2.6/trunk/3.12/1503-futex-prevent-requeue-pi-on-same-futex-patch-futex-forbid-uaddr-uaddr2-in-futex_requeue-requeue_pi-1.patch (rev 0) +++ genpatches-2.6/trunk/3.12/1503-futex-prevent-requeue-pi-on-same-futex-patch-futex-forbid-uaddr-uaddr2-in-futex_requeue-requeue_pi-1.patch 2014-06-05 22:20:47 UTC (rev 2806) @@ -0,0 +1,81 @@ +From: Thomas Gleixner <t...@linutronix.de> +Date: Tue, 3 Jun 2014 12:27:06 +0000 +Subject: futex-prevent-requeue-pi-on-same-futex.patch futex: Forbid uaddr == + uaddr2 in futex_requeue(..., requeue_pi=1) +Git-commit: e9c243a5a6de0be8e584c604d353412584b592f8 + +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 <w...@chromium.org> +Signed-off-by: Kees Cook <keesc...@chromium.org> +Cc: sta...@vger.kernel.org +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Reviewed-by: Darren Hart <dvh...@linux.intel.com> +Signed-off-by: Linus Torvalds <torva...@linux-foundation.org> +--- + kernel/futex.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +Index: linux-3.12/kernel/futex.c +=================================================================== +--- linux-3.12.orig/kernel/futex.c ++++ linux-3.12/kernel/futex.c +@@ -1295,6 +1295,13 @@ static int futex_requeue(u32 __user *uad + + if (requeue_pi) { + /* ++ * Requeue PI only works on two distinct uaddrs. This ++ * check is only valid for private futexes. See below. ++ */ ++ if (uaddr1 == uaddr2) ++ return -EINVAL; ++ ++ /* + * requeue_pi requires a pi_state, try to allocate it now + * without any locks in case it fails. + */ +@@ -1332,6 +1339,15 @@ retry: + if (unlikely(ret != 0)) + goto out_put_key1; + ++ /* ++ * The check above which compares uaddrs is not sufficient for ++ * shared futexes. We need to compare the keys: ++ */ ++ if (requeue_pi && match_futex(&key1, &key2)) { ++ ret = -EINVAL; ++ goto out_put_keys; ++ } ++ + hb1 = hash_futex(&key1); + hb2 = hash_futex(&key2); + +@@ -2362,6 +2378,15 @@ static int futex_wait_requeue_pi(u32 __u + if (ret) + goto out_key2; + ++ /* ++ * The check above which compares uaddrs is not sufficient for ++ * shared futexes. We need to compare the keys: ++ */ ++ if (match_futex(&q.key, &key2)) { ++ ret = -EINVAL; ++ goto out_put_keys; ++ } ++ + /* Queue the futex_q, drop the hb lock, wait for wakeup. */ + futex_wait_queue_me(hb, &q, to); + Added: genpatches-2.6/trunk/3.12/1504-futex-validate-atomic-acquisition-in-futex_lock_pi_atomic.patch =================================================================== --- genpatches-2.6/trunk/3.12/1504-futex-validate-atomic-acquisition-in-futex_lock_pi_atomic.patch (rev 0) +++ genpatches-2.6/trunk/3.12/1504-futex-validate-atomic-acquisition-in-futex_lock_pi_atomic.patch 2014-06-05 22:20:47 UTC (rev 2806) @@ -0,0 +1,53 @@ +From: Thomas Gleixner <t...@linutronix.de> +Date: Tue, 3 Jun 2014 12:27:06 +0000 +Subject: futex: Validate atomic acquisition in futex_lock_pi_atomic() +Git-commit: b3eaa9fc5cd0a4d74b18f6b8dc617aeaf1873270 + +We need to protect the atomic acquisition in the kernel against rogue +user space which sets the user space futex to 0, so the kernel side +acquisition succeeds while there is existing state in the kernel +associated to the real owner. + +Verify whether the futex has waiters associated with kernel state. If +it has, return -EINVAL. The state is corrupted already, so no point in +cleaning it up. Subsequent calls will fail as well. Not our problem. + +[ tglx: Use futex_top_waiter() and explain why we do not need to try + restoring the already corrupted user space state. ] + +Signed-off-by: Darren Hart <dvh...@linux.intel.com> +Cc: Kees Cook <keesc...@chromium.org> +Cc: Will Drewry <w...@chromium.org> +Cc: sta...@vger.kernel.org +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Signed-off-by: Linus Torvalds <torva...@linux-foundation.org> +--- + kernel/futex.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +Index: linux-3.12/kernel/futex.c +=================================================================== +--- linux-3.12.orig/kernel/futex.c ++++ linux-3.12/kernel/futex.c +@@ -764,10 +764,18 @@ retry: + return -EDEADLK; + + /* +- * Surprise - we got the lock. Just return to userspace: ++ * Surprise - we got the lock, but we do not trust user space at all. + */ +- if (unlikely(!curval)) +- return 1; ++ if (unlikely(!curval)) { ++ /* ++ * We verify whether there is kernel state for this ++ * futex. If not, we can safely assume, that the 0 -> ++ * TID transition is correct. If state exists, we do ++ * not bother to fixup the user space state as it was ++ * corrupted already. ++ */ ++ return futex_top_waiter(hb, key) ? -EINVAL : 1; ++ } + + uval = curval; + Added: genpatches-2.6/trunk/3.12/1505-futex-always-cleanup-owner-tid-in-unlock_pi.patch =================================================================== --- genpatches-2.6/trunk/3.12/1505-futex-always-cleanup-owner-tid-in-unlock_pi.patch (rev 0) +++ genpatches-2.6/trunk/3.12/1505-futex-always-cleanup-owner-tid-in-unlock_pi.patch 2014-06-05 22:20:47 UTC (rev 2806) @@ -0,0 +1,99 @@ +From: Thomas Gleixner <t...@linutronix.de> +Date: Tue, 3 Jun 2014 12:27:07 +0000 +Subject: futex: Always cleanup owner tid in unlock_pi +Git-commit: 13fbca4c6ecd96ec1a1cfa2e4f2ce191fe928a5e + +If the owner died bit is set at futex_unlock_pi, we currently do not +cleanup the user space futex. So the owner TID of the current owner +(the unlocker) persists. That's observable inconsistant state, +especially when the ownership of the pi state got transferred. + +Clean it up unconditionally. + +Signed-off-by: Thomas Gleixner <t...@linutronix.de> +Cc: Kees Cook <keesc...@chromium.org> +Cc: Will Drewry <w...@chromium.org> +Cc: Darren Hart <dvh...@linux.intel.com> +Cc: sta...@vger.kernel.org +Signed-off-by: Linus Torvalds <torva...@linux-foundation.org> +--- + kernel/futex.c | 40 ++++++++++++++++++---------------------- + 1 file changed, 18 insertions(+), 22 deletions(-) + +Index: linux-3.12/kernel/futex.c +=================================================================== +--- linux-3.12.orig/kernel/futex.c ++++ linux-3.12/kernel/futex.c +@@ -905,6 +905,7 @@ static int wake_futex_pi(u32 __user *uad + struct task_struct *new_owner; + struct futex_pi_state *pi_state = this->pi_state; + u32 uninitialized_var(curval), newval; ++ int ret = 0; + + if (!pi_state) + return -EINVAL; +@@ -928,23 +929,19 @@ static int wake_futex_pi(u32 __user *uad + new_owner = this->task; + + /* +- * We pass it to the next owner. (The WAITERS bit is always +- * kept enabled while there is PI state around. We must also +- * preserve the owner died bit.) +- */ +- if (!(uval & FUTEX_OWNER_DIED)) { +- int ret = 0; +- +- newval = FUTEX_WAITERS | task_pid_vnr(new_owner); +- +- if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) +- ret = -EFAULT; +- else if (curval != uval) +- ret = -EINVAL; +- if (ret) { +- raw_spin_unlock(&pi_state->pi_mutex.wait_lock); +- return ret; +- } ++ * We pass it to the next owner. The WAITERS bit is always ++ * kept enabled while there is PI state around. We cleanup the ++ * owner died bit, because we are the owner. ++ */ ++ newval = FUTEX_WAITERS | task_pid_vnr(new_owner); ++ ++ if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) ++ ret = -EFAULT; ++ else if (curval != uval) ++ ret = -EINVAL; ++ if (ret) { ++ raw_spin_unlock(&pi_state->pi_mutex.wait_lock); ++ return ret; + } + + raw_spin_lock_irq(&pi_state->owner->pi_lock); +@@ -2189,9 +2186,10 @@ retry: + /* + * To avoid races, try to do the TID -> 0 atomic transition + * again. If it succeeds then we can return without waking +- * anyone else up: ++ * anyone else up. We only try this if neither the waiters nor ++ * the owner died bit are set. + */ +- if (!(uval & FUTEX_OWNER_DIED) && ++ if (!(uval & ~FUTEX_TID_MASK) && + cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0)) + goto pi_faulted; + /* +@@ -2223,11 +2221,9 @@ retry: + /* + * No waiters - kernel unlocks the futex: + */ +- if (!(uval & FUTEX_OWNER_DIED)) { +- ret = unlock_futex_pi(uaddr, uval); +- if (ret == -EFAULT) +- goto pi_faulted; +- } ++ ret = unlock_futex_pi(uaddr, uval); ++ if (ret == -EFAULT) ++ goto pi_faulted; + + out_unlock: + spin_unlock(&hb->lock); Added: genpatches-2.6/trunk/3.12/1506-futex-make-lookup_pi_state-more-robust.patch =================================================================== (Binary files differ) Index: genpatches-2.6/trunk/3.12/1506-futex-make-lookup_pi_state-more-robust.patch =================================================================== --- genpatches-2.6/trunk/3.12/1506-futex-make-lookup_pi_state-more-robust.patch 2014-06-03 22:10:40 UTC (rev 2805) +++ genpatches-2.6/trunk/3.12/1506-futex-make-lookup_pi_state-more-robust.patch 2014-06-05 22:20:47 UTC (rev 2806) Property changes on: genpatches-2.6/trunk/3.12/1506-futex-make-lookup_pi_state-more-robust.patch ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +message/rfc822 \ No newline at end of property