Index: /trunk/server/common/patches/cve-2014-3153-0.patch
===================================================================
--- /trunk/server/common/patches/cve-2014-3153-0.patch	(revision 2557)
+++ /trunk/server/common/patches/cve-2014-3153-0.patch	(revision 2557)
@@ -0,0 +1,165 @@
+From cabef9fee397081ec3dfbde2955d4db675a96a4a Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Mon, 12 May 2014 20:45:34 +0000
+Subject: [PATCH 1/1] futex: Add another early deadlock detection check
+
+commit 866293ee54227584ffcb4a42f69c1f365974ba7f upstream.
+
+Dave Jones trinity syscall fuzzer exposed an issue in the deadlock
+detection code of rtmutex:
+  http://lkml.kernel.org/r/20140429151655.GA14277@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 <tglx@linutronix.de>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Darren Hart <darren@dvhart.com>
+Cc: Davidlohr Bueso <davidlohr@hp.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Clark Williams <williams@redhat.com>
+Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
+Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
+Cc: Roland McGrath <roland@hack.frob.com>
+Cc: Carlos ODonell <carlos@redhat.com>
+Cc: Jakub Jelinek <jakub@redhat.com>
+Cc: Michael Kerrisk <mtk.manpages@gmail.com>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: http://lkml.kernel.org/r/20140512201701.097349971@linutronix.de
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/futex.c |   47 ++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 3bc18bf..66af37d 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -594,7 +594,8 @@ void exit_pi_state_list(struct task_struct *curr)
+ 
+ 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;
+@@ -638,6 +639,16 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
+ 					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;
+ 
+@@ -787,7 +798,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) {
+@@ -1197,7 +1208,7 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
+  *
+  * 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,
+@@ -1208,7 +1219,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
+ {
+ 	struct futex_q *top_waiter = NULL;
+ 	u32 curval;
+-	int ret;
++	int ret, vpid;
+ 
+ 	if (get_futex_value_locked(&curval, pifutex))
+ 		return -EFAULT;
+@@ -1236,11 +1247,13 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
+ 	 * 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;
+ }
+ 
+@@ -1272,7 +1285,6 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
+ 	struct futex_hash_bucket *hb1, *hb2;
+ 	struct plist_head *head1;
+ 	struct futex_q *this, *next;
+-	u32 curval2;
+ 
+ 	if (requeue_pi) {
+ 		/*
+@@ -1358,16 +1370,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) {
+-- 
+1.7.10.4
+
Index: /trunk/server/common/patches/cve-2014-3153-1.patch
===================================================================
--- /trunk/server/common/patches/cve-2014-3153-1.patch	(revision 2557)
+++ /trunk/server/common/patches/cve-2014-3153-1.patch	(revision 2557)
@@ -0,0 +1,87 @@
+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/kernel/futex.c
++++ b/kernel/futex.c
+@@ -1293,6 +1293,13 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
+ 
+ 	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.
+ 		 */
+@@ -1330,6 +1337,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);
+ 
+@@ -2360,6 +2376,15 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
+ 	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);
+ 
+-- 
+1.7.10.4
+
Index: /trunk/server/common/patches/cve-2014-3153-2.patch
===================================================================
--- /trunk/server/common/patches/cve-2014-3153-2.patch	(revision 2557)
+++ /trunk/server/common/patches/cve-2014-3153-2.patch	(revision 2557)
@@ -0,0 +1,59 @@
+From 63d6ad59dd43f44249150aa8c72eeb01bbe0a599 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 3 Jun 2014 12:27:06 +0000
+Subject: [PATCH 2/4] futex: Validate atomic acquisition in
+ futex_lock_pi_atomic()
+
+commit b3eaa9fc5cd0a4d74b18f6b8dc617aeaf1873270 upstream.
+
+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 <dvhart@linux.intel.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Will Drewry <wad@chromium.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/futex.c |   14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 93e522f..8c1e6d0 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -762,10 +762,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;
+ 
+-- 
+1.7.10.4
+
Index: /trunk/server/common/patches/cve-2014-3153-3.patch
===================================================================
--- /trunk/server/common/patches/cve-2014-3153-3.patch	(revision 2557)
+++ /trunk/server/common/patches/cve-2014-3153-3.patch	(revision 2557)
@@ -0,0 +1,102 @@
+From 9ad5dabd87e8dd5506529e12e4e8c7b25fb88d7a Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 3 Jun 2014 12:27:07 +0000
+Subject: [PATCH 3/4] futex: Always cleanup owner tid in unlock_pi
+
+commit 13fbca4c6ecd96ec1a1cfa2e4f2ce191fe928a5e upstream.
+
+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 <tglx@linutronix.de>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Will Drewry <wad@chromium.org>
+Cc: 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 |   40 ++++++++++++++++++----------------------
+ 1 file changed, 18 insertions(+), 22 deletions(-)
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 8c1e6d0..9720c42 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -903,6 +903,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
+ 	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;
+@@ -926,23 +927,19 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
+ 		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.)
++	 * 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.
+ 	 */
+-	if (!(uval & FUTEX_OWNER_DIED)) {
+-		int ret = 0;
+-
+-		newval = FUTEX_WAITERS | task_pid_vnr(new_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;
+-		}
++	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);
+@@ -2187,9 +2184,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;
+ 	/*
+@@ -2221,11 +2219,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);
+-- 
+1.7.10.4
+
Index: /trunk/server/common/patches/cve-2014-3153-4.patch
===================================================================
--- /trunk/server/common/patches/cve-2014-3153-4.patch	(revision 2557)
+++ /trunk/server/common/patches/cve-2014-3153-4.patch	(revision 2557)
@@ -0,0 +1,281 @@
+From efccdcdb63a7f7cc7cc1816f0d5e2524eb084c72 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 3 Jun 2014 12:27:08 +0000
+Subject: [PATCH 4/4] futex: Make lookup_pi_state more robust
+
+commit 54a217887a7b658e2650c3feff22756ab80c7339 upstream.
+
+The current implementation of lookup_pi_state has ambigous handling of
+the TID value 0 in the user space futex.  We can get into the kernel
+even if the TID value is 0, because either there is a stale waiters bit
+or the owner died bit is set or we are called from the requeue_pi path
+or from user space just for fun.
+
+The current code avoids an explicit sanity check for pid = 0 in case
+that kernel internal state (waiters) are found for the user space
+address.  This can lead to state leakage and worse under some
+circumstances.
+
+Handle the cases explicit:
+
+       Waiter | pi_state | pi->owner | uTID      | uODIED | ?
+
+  [1]  NULL   | ---      | ---       | 0         | 0/1    | Valid
+  [2]  NULL   | ---      | ---       | >0        | 0/1    | Valid
+
+  [3]  Found  | NULL     | --        | Any       | 0/1    | Invalid
+
+  [4]  Found  | Found    | NULL      | 0         | 1      | Valid
+  [5]  Found  | Found    | NULL      | >0        | 1      | Invalid
+
+  [6]  Found  | Found    | task      | 0         | 1      | Valid
+
+  [7]  Found  | Found    | NULL      | Any       | 0      | Invalid
+
+  [8]  Found  | Found    | task      | ==taskTID | 0/1    | Valid
+  [9]  Found  | Found    | task      | 0         | 0      | Invalid
+  [10] Found  | Found    | task      | !=taskTID | 0/1    | Invalid
+
+ [1] Indicates that the kernel can acquire the futex atomically. We
+     came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
+
+ [2] Valid, if TID does not belong to a kernel thread. If no matching
+     thread is found then it indicates that the owner TID has died.
+
+ [3] Invalid. The waiter is queued on a non PI futex
+
+ [4] Valid state after exit_robust_list(), which sets the user space
+     value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
+
+ [5] The user space value got manipulated between exit_robust_list()
+     and exit_pi_state_list()
+
+ [6] Valid state after exit_pi_state_list() which sets the new owner in
+     the pi_state but cannot access the user space value.
+
+ [7] pi_state->owner can only be NULL when the OWNER_DIED bit is set.
+
+ [8] Owner and user space value match
+
+ [9] There is no transient state which sets the user space TID to 0
+     except exit_robust_list(), but this is indicated by the
+     FUTEX_OWNER_DIED bit. See [4]
+
+[10] There is no transient state which leaves owner and user space
+     TID out of sync.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Will Drewry <wad@chromium.org>
+Cc: 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 |  134 ++++++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 106 insertions(+), 28 deletions(-)
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 9720c42..625a4e6 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -592,10 +592,58 @@ void exit_pi_state_list(struct task_struct *curr)
+ 	raw_spin_unlock_irq(&curr->pi_lock);
+ }
+ 
++/*
++ * We need to check the following states:
++ *
++ *      Waiter | pi_state | pi->owner | uTID      | uODIED | ?
++ *
++ * [1]  NULL   | ---      | ---       | 0         | 0/1    | Valid
++ * [2]  NULL   | ---      | ---       | >0        | 0/1    | Valid
++ *
++ * [3]  Found  | NULL     | --        | Any       | 0/1    | Invalid
++ *
++ * [4]  Found  | Found    | NULL      | 0         | 1      | Valid
++ * [5]  Found  | Found    | NULL      | >0        | 1      | Invalid
++ *
++ * [6]  Found  | Found    | task      | 0         | 1      | Valid
++ *
++ * [7]  Found  | Found    | NULL      | Any       | 0      | Invalid
++ *
++ * [8]  Found  | Found    | task      | ==taskTID | 0/1    | Valid
++ * [9]  Found  | Found    | task      | 0         | 0      | Invalid
++ * [10] Found  | Found    | task      | !=taskTID | 0/1    | Invalid
++ *
++ * [1]	Indicates that the kernel can acquire the futex atomically. We
++ *	came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
++ *
++ * [2]	Valid, if TID does not belong to a kernel thread. If no matching
++ *      thread is found then it indicates that the owner TID has died.
++ *
++ * [3]	Invalid. The waiter is queued on a non PI futex
++ *
++ * [4]	Valid state after exit_robust_list(), which sets the user space
++ *	value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
++ *
++ * [5]	The user space value got manipulated between exit_robust_list()
++ *	and exit_pi_state_list()
++ *
++ * [6]	Valid state after exit_pi_state_list() which sets the new owner in
++ *	the pi_state but cannot access the user space value.
++ *
++ * [7]	pi_state->owner can only be NULL when the OWNER_DIED bit is set.
++ *
++ * [8]	Owner and user space value match
++ *
++ * [9]	There is no transient state which sets the user space TID to 0
++ *	except exit_robust_list(), but this is indicated by the
++ *	FUTEX_OWNER_DIED bit. See [4]
++ *
++ * [10] There is no transient state which leaves owner and user space
++ *	TID out of sync.
++ */
+ static int
+ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
+-		union futex_key *key, struct futex_pi_state **ps,
+-		struct task_struct *task)
++		union futex_key *key, struct futex_pi_state **ps)
+ {
+ 	struct futex_pi_state *pi_state = NULL;
+ 	struct futex_q *this, *next;
+@@ -608,12 +656,13 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
+ 	plist_for_each_entry_safe(this, next, head, list) {
+ 		if (match_futex(&this->key, key)) {
+ 			/*
+-			 * Another waiter already exists - bump up
+-			 * the refcount and return its pi_state:
++			 * Sanity check the waiter before increasing
++			 * the refcount and attaching to it.
+ 			 */
+ 			pi_state = this->pi_state;
+ 			/*
+-			 * Userspace might have messed up non-PI and PI futexes
++			 * Userspace might have messed up non-PI and
++			 * PI futexes [3]
+ 			 */
+ 			if (unlikely(!pi_state))
+ 				return -EINVAL;
+@@ -621,44 +670,70 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
+ 			WARN_ON(!atomic_read(&pi_state->refcount));
+ 
+ 			/*
+-			 * When pi_state->owner is NULL then the owner died
+-			 * and another waiter is on the fly. pi_state->owner
+-			 * is fixed up by the task which acquires
+-			 * pi_state->rt_mutex.
+-			 *
+-			 * We do not check for pid == 0 which can happen when
+-			 * the owner died and robust_list_exit() cleared the
+-			 * TID.
++			 * Handle the owner died case:
+ 			 */
+-			if (pid && pi_state->owner) {
++			if (uval & FUTEX_OWNER_DIED) {
+ 				/*
+-				 * Bail out if user space manipulated the
+-				 * futex value.
++				 * exit_pi_state_list sets owner to NULL and
++				 * wakes the topmost waiter. The task which
++				 * acquires the pi_state->rt_mutex will fixup
++				 * owner.
+ 				 */
+-				if (pid != task_pid_vnr(pi_state->owner))
++				if (!pi_state->owner) {
++					/*
++					 * No pi state owner, but the user
++					 * space TID is not 0. Inconsistent
++					 * state. [5]
++					 */
++					if (pid)
++						return -EINVAL;
++					/*
++					 * Take a ref on the state and
++					 * return. [4]
++					 */
++					goto out_state;
++				}
++
++				/*
++				 * If TID is 0, then either the dying owner
++				 * has not yet executed exit_pi_state_list()
++				 * or some waiter acquired the rtmutex in the
++				 * pi state, but did not yet fixup the TID in
++				 * user space.
++				 *
++				 * Take a ref on the state and return. [6]
++				 */
++				if (!pid)
++					goto out_state;
++			} else {
++				/*
++				 * If the owner died bit is not set,
++				 * then the pi_state must have an
++				 * owner. [7]
++				 */
++				if (!pi_state->owner)
+ 					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.
++			 * Bail out if user space manipulated the
++			 * futex value. If pi state exists then the
++			 * owner TID must be the same as the user
++			 * space TID. [9/10]
+ 			 */
+-			if (task && pi_state->owner == task)
+-				return -EDEADLK;
++			if (pid != task_pid_vnr(pi_state->owner))
++				return -EINVAL;
+ 
++		out_state:
+ 			atomic_inc(&pi_state->refcount);
+ 			*ps = pi_state;
+-
+ 			return 0;
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * We are the first waiter - try to look up the real owner and attach
+-	 * the new pi_state to it, but bail out when TID = 0
++	 * the new pi_state to it, but bail out when TID = 0 [1]
+ 	 */
+ 	if (!pid)
+ 		return -ESRCH;
+@@ -691,6 +766,9 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
+ 		return ret;
+ 	}
+ 
++	/*
++	 * No existing pi state. First waiter. [2]
++	 */
+ 	pi_state = alloc_pi_state();
+ 
+ 	/*
+@@ -811,7 +889,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, task);
++	ret = lookup_pi_state(uval, hb, key, ps);
+ 
+ 	if (unlikely(ret)) {
+ 		switch (ret) {
+@@ -1414,7 +1492,7 @@ retry_private:
+ 			 * rereading and handing potential crap to
+ 			 * lookup_pi_state.
+ 			 */
+-			ret = lookup_pi_state(ret, hb2, &key2, &pi_state, NULL);
++			ret = lookup_pi_state(ret, hb2, &key2, &pi_state);
+ 		}
+ 
+ 		switch (ret) {
+-- 
+1.7.10.4
+
Index: /trunk/server/fedora/specs/kernel.spec.patch
===================================================================
--- /trunk/server/fedora/specs/kernel.spec.patch	(revision 2556)
+++ /trunk/server/fedora/specs/kernel.spec.patch	(revision 2557)
@@ -1,5 +1,5 @@
 --- kernel.spec.orig	2014-05-13 21:12:04.076585365 -0400
 +++ kernel.spec	2014-05-13 21:16:17.885587650 -0400
-@@ -783,6 +783,9 @@
+@@ -783,6 +783,16 @@
  #rhbz 976837
  Patch25065: fix-ext4-overflows.patch
@@ -8,8 +8,15 @@
 +Patch30000: cve-2014-0196.patch
 +
++# CVE-2014-3153
++Patch30001: cve-2014-3153-0.patch
++Patch30002: cve-2014-3153-1.patch
++Patch30003: cve-2014-3153-2.patch
++Patch30004: cve-2014-3153-3.patch
++Patch30005: cve-2014-3153-4.patch
++
  # END OF PATCH DEFINITIONS
  
  %endif
-@@ -1516,6 +1519,9 @@
+@@ -1516,6 +1519,16 @@
  #rhbz 976837
  ApplyPatch fix-ext4-overflows.patch
@@ -18,4 +25,11 @@
 +ApplyPatch cve-2014-0196.patch
 +
++# CVE-2014-3153
++ApplyPatch cve-2014-3153-0.patch
++ApplyPatch cve-2014-3153-1.patch
++ApplyPatch cve-2014-3153-2.patch
++ApplyPatch cve-2014-3153-3.patch
++ApplyPatch cve-2014-3153-4.patch
++
  # END OF PATCH APPLICATIONS
  
