futex: Handle futex value corruption gracefully

The WARN_ON in lookup_pi_state which complains about a mismatch
between pi_state->owner->pid and the pid which we retrieved from the
user space futex is completely bogus.

The code just emits the warning and then continues despite the fact
that it detected an inconsistent state of the futex. A conveniant way
for user space to spam the syslog.

Replace the WARN_ON by a consistency check. If the values do not match
return -EINVAL and let user space deal with the mess it created.

This also fixes the missing task_pid_vnr() when we compare the
pi_state->owner pid with the futex value.

Reported-by: Jermome Marchand <jmarchan@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Darren Hart <dvhltc@us.ibm.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: <stable@kernel.org>

+19 -2
+19 -2
kernel/futex.c
··· 530 530 return -EINVAL; 531 531 532 532 WARN_ON(!atomic_read(&pi_state->refcount)); 533 - WARN_ON(pid && pi_state->owner && 534 - pi_state->owner->pid != pid); 533 + 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 553 atomic_inc(&pi_state->refcount); 537 554 *ps = pi_state;