diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 5f589279e462..81dbe773ce4c 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -745,7 +745,8 @@ void exit_pi_state_list(struct task_struct *curr) | |||
745 | 745 | ||
746 | static int | 746 | static int |
747 | lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | 747 | lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, |
748 | union futex_key *key, struct futex_pi_state **ps) | 748 | union futex_key *key, struct futex_pi_state **ps, |
749 | struct task_struct *task) | ||
749 | { | 750 | { |
750 | struct futex_pi_state *pi_state = NULL; | 751 | struct futex_pi_state *pi_state = NULL; |
751 | struct futex_q *this, *next; | 752 | struct futex_q *this, *next; |
@@ -786,6 +787,16 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
786 | return -EINVAL; | 787 | return -EINVAL; |
787 | } | 788 | } |
788 | 789 | ||
790 | /* | ||
791 | * Protect against a corrupted uval. If uval | ||
792 | * is 0x80000000 then pid is 0 and the waiter | ||
793 | * bit is set. So the deadlock check in the | ||
794 | * calling code has failed and we did not fall | ||
795 | * into the check above due to !pid. | ||
796 | */ | ||
797 | if (task && pi_state->owner == task) | ||
798 | return -EDEADLK; | ||
799 | |||
789 | atomic_inc(&pi_state->refcount); | 800 | atomic_inc(&pi_state->refcount); |
790 | *ps = pi_state; | 801 | *ps = pi_state; |
791 | 802 | ||
@@ -803,6 +814,11 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
803 | if (!p) | 814 | if (!p) |
804 | return -ESRCH; | 815 | return -ESRCH; |
805 | 816 | ||
817 | if (!p->mm) { | ||
818 | put_task_struct(p); | ||
819 | return -EPERM; | ||
820 | } | ||
821 | |||
806 | /* | 822 | /* |
807 | * We need to look at the task state flags to figure out, | 823 | * We need to look at the task state flags to figure out, |
808 | * whether the task is exiting. To protect against the do_exit | 824 | * whether the task is exiting. To protect against the do_exit |
@@ -935,7 +951,7 @@ retry: | |||
935 | * We dont have the lock. Look up the PI state (or create it if | 951 | * We dont have the lock. Look up the PI state (or create it if |
936 | * we are the first waiter): | 952 | * we are the first waiter): |
937 | */ | 953 | */ |
938 | ret = lookup_pi_state(uval, hb, key, ps); | 954 | ret = lookup_pi_state(uval, hb, key, ps, task); |
939 | 955 | ||
940 | if (unlikely(ret)) { | 956 | if (unlikely(ret)) { |
941 | switch (ret) { | 957 | switch (ret) { |
@@ -1347,7 +1363,7 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, | |||
1347 | * | 1363 | * |
1348 | * Return: | 1364 | * Return: |
1349 | * 0 - failed to acquire the lock atomically; | 1365 | * 0 - failed to acquire the lock atomically; |
1350 | * 1 - acquired the lock; | 1366 | * >0 - acquired the lock, return value is vpid of the top_waiter |
1351 | * <0 - error | 1367 | * <0 - error |
1352 | */ | 1368 | */ |
1353 | static int futex_proxy_trylock_atomic(u32 __user *pifutex, | 1369 | static int futex_proxy_trylock_atomic(u32 __user *pifutex, |
@@ -1358,7 +1374,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex, | |||
1358 | { | 1374 | { |
1359 | struct futex_q *top_waiter = NULL; | 1375 | struct futex_q *top_waiter = NULL; |
1360 | u32 curval; | 1376 | u32 curval; |
1361 | int ret; | 1377 | int ret, vpid; |
1362 | 1378 | ||
1363 | if (get_futex_value_locked(&curval, pifutex)) | 1379 | if (get_futex_value_locked(&curval, pifutex)) |
1364 | return -EFAULT; | 1380 | return -EFAULT; |
@@ -1386,11 +1402,13 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex, | |||
1386 | * the contended case or if set_waiters is 1. The pi_state is returned | 1402 | * the contended case or if set_waiters is 1. The pi_state is returned |
1387 | * in ps in contended cases. | 1403 | * in ps in contended cases. |
1388 | */ | 1404 | */ |
1405 | vpid = task_pid_vnr(top_waiter->task); | ||
1389 | ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task, | 1406 | ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task, |
1390 | set_waiters); | 1407 | set_waiters); |
1391 | if (ret == 1) | 1408 | if (ret == 1) { |
1392 | requeue_pi_wake_futex(top_waiter, key2, hb2); | 1409 | requeue_pi_wake_futex(top_waiter, key2, hb2); |
1393 | 1410 | return vpid; | |
1411 | } | ||
1394 | return ret; | 1412 | return ret; |
1395 | } | 1413 | } |
1396 | 1414 | ||
@@ -1421,7 +1439,6 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, | |||
1421 | struct futex_pi_state *pi_state = NULL; | 1439 | struct futex_pi_state *pi_state = NULL; |
1422 | struct futex_hash_bucket *hb1, *hb2; | 1440 | struct futex_hash_bucket *hb1, *hb2; |
1423 | struct futex_q *this, *next; | 1441 | struct futex_q *this, *next; |
1424 | u32 curval2; | ||
1425 | 1442 | ||
1426 | if (requeue_pi) { | 1443 | if (requeue_pi) { |
1427 | /* | 1444 | /* |
@@ -1509,16 +1526,25 @@ retry_private: | |||
1509 | * At this point the top_waiter has either taken uaddr2 or is | 1526 | * At this point the top_waiter has either taken uaddr2 or is |
1510 | * waiting on it. If the former, then the pi_state will not | 1527 | * waiting on it. If the former, then the pi_state will not |
1511 | * exist yet, look it up one more time to ensure we have a | 1528 | * exist yet, look it up one more time to ensure we have a |
1512 | * reference to it. | 1529 | * reference to it. If the lock was taken, ret contains the |
1530 | * vpid of the top waiter task. | ||
1513 | */ | 1531 | */ |
1514 | if (ret == 1) { | 1532 | if (ret > 0) { |
1515 | WARN_ON(pi_state); | 1533 | WARN_ON(pi_state); |
1516 | drop_count++; | 1534 | drop_count++; |
1517 | task_count++; | 1535 | task_count++; |
1518 | ret = get_futex_value_locked(&curval2, uaddr2); | 1536 | /* |
1519 | if (!ret) | 1537 | * If we acquired the lock, then the user |
1520 | ret = lookup_pi_state(curval2, hb2, &key2, | 1538 | * space value of uaddr2 should be vpid. It |
1521 | &pi_state); | 1539 | * cannot be changed by the top waiter as it |
1540 | * is blocked on hb2 lock if it tries to do | ||
1541 | * so. If something fiddled with it behind our | ||
1542 | * back the pi state lookup might unearth | ||
1543 | * it. So we rather use the known value than | ||
1544 | * rereading and handing potential crap to | ||
1545 | * lookup_pi_state. | ||
1546 | */ | ||
1547 | ret = lookup_pi_state(ret, hb2, &key2, &pi_state, NULL); | ||
1522 | } | 1548 | } |
1523 | 1549 | ||
1524 | switch (ret) { | 1550 | switch (ret) { |