FAILED: patch "[PATCH] futex: Fix mm reuse handling for FUT_OFF_MMSHARED" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 3267512ad1c2cc0c7768c5b014dc2cceb398a801
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026102125-action-scroll-7041@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3267512ad1c2cc0c7768c5b014dc2cceb398a801 Mon Sep 17 00:00:00 2001
From: Jann Horn <[email protected]>
Date: Tue, 29 Sep 2026 18:31:32 +0200
Subject: [PATCH] futex: Fix mm reuse handling for FUT_OFF_MMSHARED
A FUT_OFF_MMSHARED futex is a shared futex that refers to an MM. It is possible for a process to wait on a shared futex with a different MM because a FUT_OFF_INODE waiter can be requeued onto a FUT_OFF_MMSHARED futex by another process.
This can cause FUT_OFF_MMSHARED waiters on a freed MM to consume wakeups intended for a newly allocated MM at the same address.
Fix it by keying FUT_OFF_MMSHARED using a unique 64-bit per-MM ID. Leave private futexes as before to avoid influencing the performance of the hotpath.
(Multi-threaded processes typically implicitly use FUT_OFF_MMSHARED by setting clear_child_tid such that it points into anonymous memory, which causes mm_release() in a multi-threaded mm to perform FUTEX_WAKE.)
include/linux/futex.h +11 -8
@@ -23,28 +23,32 @@ struct task_struct;* 01 : Shared futex (PTHREAD_PROCESS_SHARED) * mapped on a file (reference on the underlying inode) * 10 : Shared futex (PTHREAD_PROCESS_SHARED) -* (but private mapping on an mm, and reference taken on it) +* (but private mapping on an mm) */ -#define FUT_OFF_INODE 1/* We set bit 0 if key has a reference on inode */ -#define FUT_OFF_MMSHARED 2/* We set bit 1 if key has a reference on mm */ +#define FUT_OFF_INODE 1/* We set bit 0 if shared key identifies an inode */ +#define FUT_OFF_MMSHARED 2/* We set bit 1 if shared key identifies an mm */ union futex_key { +/* For FUT_OFF_INODE */ struct {u64 i_seq;unsigned long pgoff;unsigned int offset;/* unsigned int node; */ } shared; + +/* For FUT_OFF_MMSHARED or private */ struct {union { -struct mm_struct *mm; -u64 __tmp; +struct mm_struct *mm;/* for private */ +u64 mm_seq;/* for FUT_OFF_MMSHARED */ };unsigned long address;unsigned int offset;/* unsigned int node; */ } private; +struct {u64 ptr;unsigned long word;
@@ -152,11 +156,10 @@ static inline void futex_set_vdso_cs_range(struct futex_mm_data *fd, unsigned instatic inline void futex_fixup_robust_unlock (struct pt_regs *regs) { }#endif /* !CONFIG_FUTEX_ROBUST_UNLOCK */ - -#if defined(CONFIG_FUTEX_PRIVATE_HASH ) || defined(CONFIG_FUTEX_ROBUST_UNLOCK ) +#ifdef CONFIG_FUTEX void futex_mm_init (struct mm_struct *mm);#else static inline void futex_mm_init (struct mm_struct *mm) { } -#endif +#endif /* !CONFIG_FUTEX */ #endif /* _LINUX_FUTEX_H */
include/linux/futex_types.h +2 -0
@@ -85,10 +85,12 @@ struct futex_unlock_cs_ranges { };* struct futex_mm_data - Futex related per MM data * @phash: Futex private hash related data * @unlock: Futex unlock VDSO critical sections +* @unique_id: Unique ID of the MM, for FUT_OFF_MMSHARED futexes */ struct futex_mm_data {struct futex_mm_phash phash;struct futex_unlock_cs_ranges unlock; +atomic64_t unique_id; };#else /* CONFIG_FUTEX */ struct futex_sched_data { };
kernel/futex/core.c +30 -25
87 lines not on this page · raw message
Sasha Levin
maintainerPATCH 1/1 futex: Fix mm reuse handling for FUT_OFF_MMSHARED
From: Jann Horn <[email protected]>
[ Upstream commit 3267512ad1c2cc0c7768c5b014dc2cceb398a801 ]
A FUT_OFF_MMSHARED futex is a shared futex that refers to an MM. It is possible for a process to wait on a shared futex with a different MM because a FUT_OFF_INODE waiter can be requeued onto a FUT_OFF_MMSHARED futex by another process.
This can cause FUT_OFF_MMSHARED waiters on a freed MM to consume wakeups intended for a newly allocated MM at the same address.
Fix it by keying FUT_OFF_MMSHARED using a unique 64-bit per-MM ID. Leave private futexes as before to avoid influencing the performance of the hotpath.
(Multi-threaded processes typically implicitly use FUT_OFF_MMSHARED by setting clear_child_tid such that it points into anonymous memory, which causes mm_release() in a multi-threaded mm to perform FUTEX_WAKE.)
--- include/linux/futex.h | 14 ++++++++---- include/linux/mm_types.h | 4 ++++ kernel/fork.c | 3 +++ kernel/futex/core.c | 49 +++++++++++++++++++++------------------- 4 files changed, 42 insertions(+), 28 deletions(-)
include/linux/futex.h +9 -5
@@ -23,26 +23,30 @@ struct task_struct;* 01 : Shared futex (PTHREAD_PROCESS_SHARED) * mapped on a file (reference on the underlying inode) * 10 : Shared futex (PTHREAD_PROCESS_SHARED) -* (but private mapping on an mm, and reference taken on it) +* (but private mapping on an mm) */ -#define FUT_OFF_INODE 1/* We set bit 0 if key has a reference on inode */ -#define FUT_OFF_MMSHARED 2/* We set bit 1 if key has a reference on mm */ +#define FUT_OFF_INODE 1/* We set bit 0 if shared key identifies an inode */ +#define FUT_OFF_MMSHARED 2/* We set bit 1 if shared key identifies an mm */ union futex_key { +/* For FUT_OFF_INODE */ struct {u64 i_seq;unsigned long pgoff;unsigned int offset; } shared; + +/* For FUT_OFF_MMSHARED or private */ struct {union { -struct mm_struct *mm; -u64 __tmp; +struct mm_struct *mm;/* for private */ +u64 mm_seq;/* for FUT_OFF_MMSHARED */ };unsigned long address;unsigned int offset; } private; +struct {u64 ptr;unsigned long word;
include/linux/mm_types.h +4 -0
@@ -580,6 +580,10 @@ struct mm_struct {#endif struct work_struct async_put_work; +#ifdef CONFIG_FUTEX +atomic64_t futex_unique_id; +#endif +#ifdef CONFIG_IOMMU_SUPPORT u32 pasid;#endif
kernel/fork.c +3 -0
@@ -1082,6 +1082,9 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,#endif mm_init_uprobes_state (mm);hugetlb_count_init (mm); +#ifdef CONFIG_FUTEX +atomic64_set (&mm->futex_unique_id,0 ); +#endif if (current->mm) { mm->flags = current->mm->flags &MMF_INIT_MASK ;
kernel/futex/core.c +26 -23
87 lines not on this page · raw message
Signature · 1 line
2.53.0