aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index d077201b393d..f0dea283e77e 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -115,6 +115,9 @@ struct futex_q {
115 /* rt_waiter storage for requeue_pi: */ 115 /* rt_waiter storage for requeue_pi: */
116 struct rt_mutex_waiter *rt_waiter; 116 struct rt_mutex_waiter *rt_waiter;
117 117
118 /* The expected requeue pi target futex key: */
119 union futex_key *requeue_pi_key;
120
118 /* Bitset for the optional bitmasked wakeup */ 121 /* Bitset for the optional bitmasked wakeup */
119 u32 bitset; 122 u32 bitset;
120}; 123};
@@ -1080,6 +1083,10 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
1080 if (!top_waiter) 1083 if (!top_waiter)
1081 return 0; 1084 return 0;
1082 1085
1086 /* Ensure we requeue to the expected futex. */
1087 if (!match_futex(top_waiter->requeue_pi_key, key2))
1088 return -EINVAL;
1089
1083 /* 1090 /*
1084 * Try to take the lock for top_waiter. Set the FUTEX_WAITERS bit in 1091 * Try to take the lock for top_waiter. Set the FUTEX_WAITERS bit in
1085 * the contended case or if set_waiters is 1. The pi_state is returned 1092 * the contended case or if set_waiters is 1. The pi_state is returned
@@ -1260,6 +1267,12 @@ retry_private:
1260 continue; 1267 continue;
1261 } 1268 }
1262 1269
1270 /* Ensure we requeue to the expected futex for requeue_pi. */
1271 if (requeue_pi && !match_futex(this->requeue_pi_key, &key2)) {
1272 ret = -EINVAL;
1273 break;
1274 }
1275
1263 /* 1276 /*
1264 * Requeue nr_requeue waiters and possibly one more in the case 1277 * Requeue nr_requeue waiters and possibly one more in the case
1265 * of requeue_pi if we couldn't acquire the lock atomically. 1278 * of requeue_pi if we couldn't acquire the lock atomically.
@@ -1735,6 +1748,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
1735 q.pi_state = NULL; 1748 q.pi_state = NULL;
1736 q.bitset = bitset; 1749 q.bitset = bitset;
1737 q.rt_waiter = NULL; 1750 q.rt_waiter = NULL;
1751 q.requeue_pi_key = NULL;
1738 1752
1739 if (abs_time) { 1753 if (abs_time) {
1740 to = &timeout; 1754 to = &timeout;
@@ -1842,6 +1856,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
1842 1856
1843 q.pi_state = NULL; 1857 q.pi_state = NULL;
1844 q.rt_waiter = NULL; 1858 q.rt_waiter = NULL;
1859 q.requeue_pi_key = NULL;
1845retry: 1860retry:
1846 q.key = FUTEX_KEY_INIT; 1861 q.key = FUTEX_KEY_INIT;
1847 ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE); 1862 ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE);
@@ -2153,15 +2168,16 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
2153 debug_rt_mutex_init_waiter(&rt_waiter); 2168 debug_rt_mutex_init_waiter(&rt_waiter);
2154 rt_waiter.task = NULL; 2169 rt_waiter.task = NULL;
2155 2170
2156 q.pi_state = NULL;
2157 q.bitset = bitset;
2158 q.rt_waiter = &rt_waiter;
2159
2160 key2 = FUTEX_KEY_INIT; 2171 key2 = FUTEX_KEY_INIT;
2161 ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE); 2172 ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
2162 if (unlikely(ret != 0)) 2173 if (unlikely(ret != 0))
2163 goto out; 2174 goto out;
2164 2175
2176 q.pi_state = NULL;
2177 q.bitset = bitset;
2178 q.rt_waiter = &rt_waiter;
2179 q.requeue_pi_key = &key2;
2180
2165 /* Prepare to wait on uaddr. */ 2181 /* Prepare to wait on uaddr. */
2166 ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); 2182 ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
2167 if (ret) 2183 if (ret)