diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2014-06-03 16:27:08 +0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-05 23:31:07 +0400 | 
| commit | 54a217887a7b658e2650c3feff22756ab80c7339 (patch) | |
| tree | 125418b3a37dd41216b786af8e4f6a01fd4f8570 /lib/mpi/mpicoder.c | |
| parent | 13fbca4c6ecd96ec1a1cfa2e4f2ce191fe928a5e (diff) | |
| download | linux-54a217887a7b658e2650c3feff22756ab80c7339.tar.xz | |
futex: Make lookup_pi_state more robust
The current implementation of lookup_pi_state has ambigous handling of
the TID value 0 in the user space futex.  We can get into the kernel
even if the TID value is 0, because either there is a stale waiters bit
or the owner died bit is set or we are called from the requeue_pi path
or from user space just for fun.
The current code avoids an explicit sanity check for pid = 0 in case
that kernel internal state (waiters) are found for the user space
address.  This can lead to state leakage and worse under some
circumstances.
Handle the cases explicit:
       Waiter | pi_state | pi->owner | uTID      | uODIED | ?
  [1]  NULL   | ---      | ---       | 0         | 0/1    | Valid
  [2]  NULL   | ---      | ---       | >0        | 0/1    | Valid
  [3]  Found  | NULL     | --        | Any       | 0/1    | Invalid
  [4]  Found  | Found    | NULL      | 0         | 1      | Valid
  [5]  Found  | Found    | NULL      | >0        | 1      | Invalid
  [6]  Found  | Found    | task      | 0         | 1      | Valid
  [7]  Found  | Found    | NULL      | Any       | 0      | Invalid
  [8]  Found  | Found    | task      | ==taskTID | 0/1    | Valid
  [9]  Found  | Found    | task      | 0         | 0      | Invalid
  [10] Found  | Found    | task      | !=taskTID | 0/1    | Invalid
 [1] Indicates that the kernel can acquire the futex atomically. We
     came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
 [2] Valid, if TID does not belong to a kernel thread. If no matching
     thread is found then it indicates that the owner TID has died.
 [3] Invalid. The waiter is queued on a non PI futex
 [4] Valid state after exit_robust_list(), which sets the user space
     value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
 [5] The user space value got manipulated between exit_robust_list()
     and exit_pi_state_list()
 [6] Valid state after exit_pi_state_list() which sets the new owner in
     the pi_state but cannot access the user space value.
 [7] pi_state->owner can only be NULL when the OWNER_DIED bit is set.
 [8] Owner and user space value match
 [9] There is no transient state which sets the user space TID to 0
     except exit_robust_list(), but this is indicated by the
     FUTEX_OWNER_DIED bit. See [4]
[10] There is no transient state which leaves owner and user space
     TID out of sync.
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 'lib/mpi/mpicoder.c')
0 files changed, 0 insertions, 0 deletions
