Skip to content

Commit f087b0b

Browse files
committed
Merge tag 'locking-urgent-2026-03-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull futex fixes from Ingo Molnar: - Tighten up the sys_futex_requeue() ABI a bit, to disallow dissimilar futex flags and potential UaF access (Peter Zijlstra) - Fix UaF between futex_key_to_node_opt() and vma_replace_policy() (Hao-Yu Yang) - Clear stale exiting pointer in futex_lock_pi() retry path, which triggered a warning (and potential misbehavior) in stress-testing (Davidlohr Bueso) * tag 'locking-urgent-2026-03-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: futex: Clear stale exiting pointer in futex_lock_pi() retry path futex: Fix UaF between futex_key_to_node_opt() and vma_replace_policy() futex: Require sys_futex_requeue() to have identical flags
2 parents 21047b1 + 210d36d commit f087b0b

5 files changed

Lines changed: 20 additions & 4 deletions

File tree

include/linux/mempolicy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct mempolicy {
5555
nodemask_t cpuset_mems_allowed; /* relative to these nodes */
5656
nodemask_t user_nodemask; /* nodemask passed by user */
5757
} w;
58+
struct rcu_head rcu;
5859
};
5960

6061
/*

kernel/futex/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ static int __futex_key_to_node(struct mm_struct *mm, unsigned long addr)
342342
if (!vma)
343343
return FUTEX_NO_NODE;
344344

345-
mpol = vma_policy(vma);
345+
mpol = READ_ONCE(vma->vm_policy);
346346
if (!mpol)
347347
return FUTEX_NO_NODE;
348348

kernel/futex/pi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ int fixup_pi_owner(u32 __user *uaddr, struct futex_q *q, int locked)
918918
int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int trylock)
919919
{
920920
struct hrtimer_sleeper timeout, *to;
921-
struct task_struct *exiting = NULL;
921+
struct task_struct *exiting;
922922
struct rt_mutex_waiter rt_waiter;
923923
struct futex_q q = futex_q_init;
924924
DEFINE_WAKE_Q(wake_q);
@@ -933,6 +933,7 @@ int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int tryl
933933
to = futex_setup_timer(time, &timeout, flags, 0);
934934

935935
retry:
936+
exiting = NULL;
936937
ret = get_futex_key(uaddr, flags, &q.key, FUTEX_WRITE);
937938
if (unlikely(ret != 0))
938939
goto out;

kernel/futex/syscalls.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,14 @@ SYSCALL_DEFINE4(futex_requeue,
459459
if (ret)
460460
return ret;
461461

462+
/*
463+
* For now mandate both flags are identical, like the sys_futex()
464+
* interface has. If/when we merge the variable sized futex support,
465+
* that patch can modify this test to allow a difference in size.
466+
*/
467+
if (futexes[0].w.flags != futexes[1].w.flags)
468+
return -EINVAL;
469+
462470
cmpval = futexes[0].w.val;
463471

464472
return futex_requeue(u64_to_user_ptr(futexes[0].w.uaddr), futexes[0].w.flags,

mm/mempolicy.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,13 @@ void __mpol_put(struct mempolicy *pol)
487487
{
488488
if (!atomic_dec_and_test(&pol->refcnt))
489489
return;
490-
kmem_cache_free(policy_cache, pol);
490+
/*
491+
* Required to allow mmap_lock_speculative*() access, see for example
492+
* futex_key_to_node_opt(). All accesses are serialized by mmap_lock,
493+
* however the speculative lock section unbound by the normal lock
494+
* boundaries, requiring RCU freeing.
495+
*/
496+
kfree_rcu(pol, rcu);
491497
}
492498
EXPORT_SYMBOL_FOR_MODULES(__mpol_put, "kvm");
493499

@@ -1020,7 +1026,7 @@ static int vma_replace_policy(struct vm_area_struct *vma,
10201026
}
10211027

10221028
old = vma->vm_policy;
1023-
vma->vm_policy = new; /* protected by mmap_lock */
1029+
WRITE_ONCE(vma->vm_policy, new); /* protected by mmap_lock */
10241030
mpol_put(old);
10251031

10261032
return 0;

0 commit comments

Comments
 (0)