futex: compare keys for equality when doing a FUTEX_UNLOCK_PI.

PiperOrigin-RevId: 256453827
This commit is contained in:
Neel Natu
2019-07-03 16:01:38 -07:00
committed by gVisor bot
parent 116cac053e
commit 9f2f9f0cab
+19 -6
View File
@@ -729,14 +729,14 @@ func (m *Manager) UnlockPI(t Target, addr usermem.Addr, tid uint32, private bool
}
b := m.lockBucket(&k)
err = m.unlockPILocked(t, addr, tid, b)
err = m.unlockPILocked(t, addr, tid, b, &k)
k.release()
b.mu.Unlock()
return err
}
func (m *Manager) unlockPILocked(t Target, addr usermem.Addr, tid uint32, b *bucket) error {
func (m *Manager) unlockPILocked(t Target, addr usermem.Addr, tid uint32, b *bucket, key *Key) error {
cur, err := t.LoadUint32(addr)
if err != nil {
return err
@@ -746,7 +746,22 @@ func (m *Manager) unlockPILocked(t Target, addr usermem.Addr, tid uint32, b *buc
return syserror.EPERM
}
if b.waiters.Empty() {
var next *Waiter // Who's the next owner?
var next2 *Waiter // Who's the one after that?
for w := b.waiters.Front(); w != nil; w = w.Next() {
if !w.key.matches(key) {
continue
}
if next == nil {
next = w
} else {
next2 = w
break
}
}
if next == nil {
// It's safe to set 0 because there are no waiters, no new owner, and the
// executing task is the current owner (no owner died bit).
prev, err := t.CompareAndSwapUint32(addr, cur, 0)
@@ -761,12 +776,10 @@ func (m *Manager) unlockPILocked(t Target, addr usermem.Addr, tid uint32, b *buc
return nil
}
next := b.waiters.Front()
// Set next owner's TID, waiters if there are any. Resets owner died bit, if
// set, because the executing task takes over as the owner.
val := next.tid
if next.Next() != nil {
if next2 != nil {
val |= linux.FUTEX_WAITERS
}