aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-06-03 08:27:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-05 15:31:07 -0400
commit13fbca4c6ecd96ec1a1cfa2e4f2ce191fe928a5e (patch)
tree8789bcd2b04e6dbceda2377ca67575e5fa618876 /kernel/futex.c
parentb3eaa9fc5cd0a4d74b18f6b8dc617aeaf1873270 (diff)
futex: Always cleanup owner tid in unlock_pi
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> Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 520e7b23bf3c..e1cb1baa23fb 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1052,6 +1052,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
1052 struct task_struct *new_owner; 1052 struct task_struct *new_owner;
1053 struct futex_pi_state *pi_state = this->pi_state; 1053 struct futex_pi_state *pi_state = this->pi_state;
1054 u32 uninitialized_var(curval), newval; 1054 u32 uninitialized_var(curval), newval;
1055 int ret = 0;
1055 1056
1056 if (!pi_state) 1057 if (!pi_state)
1057 return -EINVAL; 1058 return -EINVAL;
@@ -1075,23 +1076,19 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
1075 new_owner = this->task; 1076 new_owner = this->task;
1076 1077
1077 /* 1078 /*
1078 * We pass it to the next owner. (The WAITERS bit is always 1079 * We pass it to the next owner. The WAITERS bit is always
1079 * kept enabled while there is PI state around. We must also 1080 * kept enabled while there is PI state around. We cleanup the
1080 * preserve the owner died bit.) 1081 * owner died bit, because we are the owner.
1081 */ 1082 */
1082 if (!(uval & FUTEX_OWNER_DIED)) { 1083 newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
1083 int ret = 0;
1084
1085 newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
1086 1084
1087 if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) 1085 if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
1088 ret = -EFAULT; 1086 ret = -EFAULT;
1089 else if (curval != uval) 1087 else if (curval != uval)
1090 ret = -EINVAL; 1088 ret = -EINVAL;
1091 if (ret) { 1089 if (ret) {
1092 raw_spin_unlock(&pi_state->pi_mutex.wait_lock); 1090 raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
1093 return ret; 1091 return ret;
1094 }
1095 } 1092 }
1096 1093
1097 raw_spin_lock_irq(&pi_state->owner->pi_lock); 1094 raw_spin_lock_irq(&pi_state->owner->pi_lock);
@@ -2351,9 +2348,10 @@ retry:
2351 /* 2348 /*
2352 * To avoid races, try to do the TID -> 0 atomic transition 2349 * To avoid races, try to do the TID -> 0 atomic transition
2353 * again. If it succeeds then we can return without waking 2350 * again. If it succeeds then we can return without waking
2354 * anyone else up: 2351 * anyone else up. We only try this if neither the waiters nor
2352 * the owner died bit are set.
2355 */ 2353 */
2356 if (!(uval & FUTEX_OWNER_DIED) && 2354 if (!(uval & ~FUTEX_TID_MASK) &&
2357 cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0)) 2355 cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0))
2358 goto pi_faulted; 2356 goto pi_faulted;
2359 /* 2357 /*
@@ -2383,11 +2381,9 @@ retry:
2383 /* 2381 /*
2384 * No waiters - kernel unlocks the futex: 2382 * No waiters - kernel unlocks the futex:
2385 */ 2383 */
2386 if (!(uval & FUTEX_OWNER_DIED)) { 2384 ret = unlock_futex_pi(uaddr, uval);
2387 ret = unlock_futex_pi(uaddr, uval); 2385 if (ret == -EFAULT)
2388 if (ret == -EFAULT) 2386 goto pi_faulted;
2389 goto pi_faulted;
2390 }
2391 2387
2392out_unlock: 2388out_unlock:
2393 spin_unlock(&hb->lock); 2389 spin_unlock(&hb->lock);