diff options
Diffstat (limited to 'kernel/futex.c')
| -rw-r--r-- | kernel/futex.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index d9b3a2228f9d..e7a35f1039e7 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -530,8 +530,25 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
| 530 | return -EINVAL; | 530 | return -EINVAL; |
| 531 | 531 | ||
| 532 | WARN_ON(!atomic_read(&pi_state->refcount)); | 532 | WARN_ON(!atomic_read(&pi_state->refcount)); |
| 533 | WARN_ON(pid && pi_state->owner && | 533 | |
| 534 | pi_state->owner->pid != pid); | 534 | /* |
| 535 | * When pi_state->owner is NULL then the owner died | ||
| 536 | * and another waiter is on the fly. pi_state->owner | ||
| 537 | * is fixed up by the task which acquires | ||
| 538 | * pi_state->rt_mutex. | ||
| 539 | * | ||
| 540 | * We do not check for pid == 0 which can happen when | ||
| 541 | * the owner died and robust_list_exit() cleared the | ||
| 542 | * TID. | ||
| 543 | */ | ||
| 544 | if (pid && pi_state->owner) { | ||
| 545 | /* | ||
| 546 | * Bail out if user space manipulated the | ||
| 547 | * futex value. | ||
| 548 | */ | ||
| 549 | if (pid != task_pid_vnr(pi_state->owner)) | ||
| 550 | return -EINVAL; | ||
| 551 | } | ||
| 535 | 552 | ||
| 536 | atomic_inc(&pi_state->refcount); | 553 | atomic_inc(&pi_state->refcount); |
| 537 | *ps = pi_state; | 554 | *ps = pi_state; |
| @@ -758,6 +775,13 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
| 758 | if (!pi_state) | 775 | if (!pi_state) |
| 759 | return -EINVAL; | 776 | return -EINVAL; |
| 760 | 777 | ||
| 778 | /* | ||
| 779 | * If current does not own the pi_state then the futex is | ||
| 780 | * inconsistent and user space fiddled with the futex value. | ||
| 781 | */ | ||
| 782 | if (pi_state->owner != current) | ||
| 783 | return -EINVAL; | ||
| 784 | |||
| 761 | raw_spin_lock(&pi_state->pi_mutex.wait_lock); | 785 | raw_spin_lock(&pi_state->pi_mutex.wait_lock); |
| 762 | new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); | 786 | new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); |
| 763 | 787 | ||
| @@ -1971,7 +1995,7 @@ retry_private: | |||
| 1971 | /* Unqueue and drop the lock */ | 1995 | /* Unqueue and drop the lock */ |
| 1972 | unqueue_me_pi(&q); | 1996 | unqueue_me_pi(&q); |
| 1973 | 1997 | ||
| 1974 | goto out; | 1998 | goto out_put_key; |
| 1975 | 1999 | ||
| 1976 | out_unlock_put_key: | 2000 | out_unlock_put_key: |
| 1977 | queue_unlock(&q, hb); | 2001 | queue_unlock(&q, hb); |
