Skip to content

Commit 69a14d1

Browse files
Sebastian Andrzej SiewiorPeter Zijlstra
authored andcommitted
futex: Verify under the lock if hash can be replaced
Once the global hash is requested there is no way back to switch back to the per-task private hash. This is checked at the begin of the function. It is possible that two threads simultaneously request the global hash and both pass the initial check and block later on the mm::futex_hash_lock. In this case the first thread performs the switch to the global hash. The second thread will also attempt to switch to the global hash and while doing so, accessing the nonexisting slot 1 of the struct futex_private_hash. The same applies if the hash is made immutable: There is no reference counting and the hash must not be replaced. Verify under mm_struct::futex_phash that neither the global hash nor an immutable hash in use. Tested-by: "Lai, Yi" <[email protected]> Reported-by: "Lai, Yi" <[email protected]> Closes: https://lore.kernel.org/all/aDwDw9Aygqo6oAx+@ly-workstation/ Fixes: bd54df5 ("futex: Allow to resize the private local hash") Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/all/[email protected]/
1 parent 8337204 commit 69a14d1

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

kernel/futex/core.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,16 @@ static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags)
16291629
mm->futex_phash_new = NULL;
16301630

16311631
if (fph) {
1632+
if (cur && (!cur->hash_mask || cur->immutable)) {
1633+
/*
1634+
* If two threads simultaneously request the global
1635+
* hash then the first one performs the switch,
1636+
* the second one returns here.
1637+
*/
1638+
free = fph;
1639+
mm->futex_phash_new = new;
1640+
return -EBUSY;
1641+
}
16321642
if (cur && !new) {
16331643
/*
16341644
* If we have an existing hash, but do not yet have

0 commit comments

Comments
 (0)