From nobody Thu Apr 2 20:38:41 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A5143806C6; Thu, 26 Mar 2026 15:16:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774538188; cv=none; b=osuMm6+inhbeqTIlTCIfPr/VGdNIFgRVbSrD2nBggDDXWijNo7CkIUvVyjGWdv6Wu11STo5M9iEdIJb4HQVDnIRgDj3D5nM4tGmsnNXtP5bXEGp4BWFK/P1ffQ7n7WnCVu5xx6LecefEPA70r1duZyxPe8ICsTKxW/9+xxcw4sY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774538188; c=relaxed/simple; bh=Ul20o5HoWKb0MLsWjjz+vVnshFzSRTT8BGPaa72tv/c=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=OreVnofIZYxxtNg+Pdj250Sa8lRq9E2enMoCk30G749zyB4LF8YOQjBka46Ae20frSmwihmT2k5A9ZvOlo+ncheVvhF2NLHW4MXUz0xcVk5Un1tZcx57VCWh9kEUT4Qo0wY44XcQX2KHJIyRZI/UricxjMc72/Z5kzaltAViggU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=BW81qBjC; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=egff62Ge; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="BW81qBjC"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="egff62Ge" Date: Thu, 26 Mar 2026 15:16:23 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1774538185; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cQfb6qkDBtxMOw4p4VmO2CrFyvqu4HM35qG1TnExHNE=; b=BW81qBjCBg5ZNbhK+q77Okhh2QaUrZEO19ohz6SfIXPCYku/o+YVxYUelsanpj0TIcTKGn HfDypQ7C8/HXBckva0x0RULYb+jHdO8trkjhq0HiW77Rl6tv5JusiID3JSGzNhtdcVOe1Z 12ps6h8KGGj5BuYsaoe00ZeKVjIrntlur1ekCX23Tie79DnRNUoZmedFCluvt+C39XhKZh 4IDc5x7i7W9JImjmNh91tjWLrm6ivxfLSBhzsRyhU58OMKLe+seoVsWaPoY3eAQuC1WiZX Xj52GWegkQXJIcBnpYN5sfF56th8lvh8FRdoRLqptIzWc2F/ipU6TnmC1qCkBQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1774538185; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cQfb6qkDBtxMOw4p4VmO2CrFyvqu4HM35qG1TnExHNE=; b=egff62GepnNkO5o9dpnOOEPlcY85fEv6dB3ha3R7CKdYmQV4uvILnP4k6L3zUypSNqfeEz etAVJTsALoeX2zCw== From: "tip-bot2 for Hao-Yu Yang" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/urgent] futex: Fix UaF between futex_key_to_node_opt() and vma_replace_policy() Cc: "Hao-Yu Yang" , Eric Dumazet , "Peter Zijlstra (Intel)" , "David Hildenbrand (Arm)" , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20260324174418.GB1850007@noisy.programming.kicks-ass.net> References: <20260324174418.GB1850007@noisy.programming.kicks-ass.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <177453818384.1647592.6524878549677929721.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the locking/urgent branch of tip: Commit-ID: 190a8c48ff623c3d67cb295b4536a660db2012aa Gitweb: https://git.kernel.org/tip/190a8c48ff623c3d67cb295b4536a660d= b2012aa Author: Hao-Yu Yang AuthorDate: Fri, 13 Mar 2026 20:47:56 +08:00 Committer: Peter Zijlstra CommitterDate: Thu, 26 Mar 2026 16:13:48 +01:00 futex: Fix UaF between futex_key_to_node_opt() and vma_replace_policy() During futex_key_to_node_opt() execution, vma->vm_policy is read under speculative mmap lock and RCU. Concurrently, mbind() may call vma_replace_policy() which frees the old mempolicy immediately via kmem_cache_free(). This creates a race where __futex_key_to_node() dereferences a freed mempolicy pointer, causing a use-after-free read of mpol->mode. [ 151.412631] BUG: KASAN: slab-use-after-free in __futex_key_to_node (kern= el/futex/core.c:349) [ 151.414046] Read of size 2 at addr ffff888001c49634 by task e/87 [ 151.415969] Call Trace: [ 151.416732] __asan_load2 (mm/kasan/generic.c:271) [ 151.416777] __futex_key_to_node (kernel/futex/core.c:349) [ 151.416822] get_futex_key (kernel/futex/core.c:374 kernel/futex/core.c:= 386 kernel/futex/core.c:593) Fix by adding rcu to __mpol_put(). Fixes: c042c505210d ("futex: Implement FUTEX2_MPOL") Reported-by: Hao-Yu Yang Suggested-by: Eric Dumazet Signed-off-by: Hao-Yu Yang Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Eric Dumazet Acked-by: David Hildenbrand (Arm) Link: https://patch.msgid.link/20260324174418.GB1850007@noisy.programming.k= icks-ass.net --- include/linux/mempolicy.h | 1 + kernel/futex/core.c | 2 +- mm/mempolicy.c | 10 ++++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 0fe96f3..65c732d 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -55,6 +55,7 @@ struct mempolicy { nodemask_t cpuset_mems_allowed; /* relative to these nodes */ nodemask_t user_nodemask; /* nodemask passed by user */ } w; + struct rcu_head rcu; }; =20 /* diff --git a/kernel/futex/core.c b/kernel/futex/core.c index cf7e610..31e83a0 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -342,7 +342,7 @@ static int __futex_key_to_node(struct mm_struct *mm, un= signed long addr) if (!vma) return FUTEX_NO_NODE; =20 - mpol =3D vma_policy(vma); + mpol =3D READ_ONCE(vma->vm_policy); if (!mpol) return FUTEX_NO_NODE; =20 diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 0e5175f..cf92bd6 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -487,7 +487,13 @@ void __mpol_put(struct mempolicy *pol) { if (!atomic_dec_and_test(&pol->refcnt)) return; - kmem_cache_free(policy_cache, pol); + /* + * Required to allow mmap_lock_speculative*() access, see for example + * futex_key_to_node_opt(). All accesses are serialized by mmap_lock, + * however the speculative lock section unbound by the normal lock + * boundaries, requiring RCU freeing. + */ + kfree_rcu(pol, rcu); } EXPORT_SYMBOL_FOR_MODULES(__mpol_put, "kvm"); =20 @@ -1020,7 +1026,7 @@ static int vma_replace_policy(struct vm_area_struct *= vma, } =20 old =3D vma->vm_policy; - vma->vm_policy =3D new; /* protected by mmap_lock */ + WRITE_ONCE(vma->vm_policy, new); /* protected by mmap_lock */ mpol_put(old); =20 return 0;