Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

futex: Drop CLONE_THREAD requirement for private default hash alloc

Currently need_futex_hash_allocate_default() depends on strict pthread
semantics, abusing CLONE_THREAD. This breaks the non-concurrency
assumptions when doing the mm->futex_ref pcpu allocations, leading to
bugs[0] when sharing the mm in other ways; ie:

BUG: KASAN: slab-use-after-free in futex_hash_put

... where the +1 bias can end up on a percpu counter that mm->futex_ref
no longer points at.

Loosen the check to cover any CLONE_VM clone, except vfork(). Excluding
vfork keeps the existing paths untouched (no overhead), and we can't
race in the first place: either the parent is suspended and the child
runs alone, or mm->futex_ref is already allocated from an earlier
CLONE_VM.

Link: https://lore.kernel.org/all/CAL_bE8LsmCQ-FAtYDuwbJhOkt9p2wwYQwAbMh=PifC=VsiBM6A@mail.gmail.com/ [0]
Fixes: d9b05321e21e ("futex: Move futex_hash_free() back to __mmput()")
Reported-by: Yiming Qian <yimingqian591@gmail.com>
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Davidlohr Bueso and committed by
Linus Torvalds
ee9dce44 bb1d73f2

+5 -7
+5 -7
kernel/fork.c
··· 1951 1951 1952 1952 static bool need_futex_hash_allocate_default(u64 clone_flags) 1953 1953 { 1954 - if ((clone_flags & (CLONE_THREAD | CLONE_VM)) != (CLONE_THREAD | CLONE_VM)) 1955 - return false; 1956 - return true; 1954 + /* 1955 + * Allocate a default futex hash for any sibling that will 1956 + * share the parent's mm, except vfork. 1957 + */ 1958 + return (clone_flags & (CLONE_VM | CLONE_VFORK)) == CLONE_VM; 1957 1959 } 1958 1960 1959 1961 /* ··· 2382 2380 if (retval) 2383 2381 goto bad_fork_cancel_cgroup; 2384 2382 2385 - /* 2386 - * Allocate a default futex hash for the user process once the first 2387 - * thread spawns. 2388 - */ 2389 2383 if (need_futex_hash_allocate_default(clone_flags)) { 2390 2384 retval = futex_hash_allocate_default(); 2391 2385 if (retval)