From nobody Sat Sep 26 07:17:00 2026 Received: from va-2-38.ptr.blmpb.com (va-2-38.ptr.blmpb.com [209.127.231.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B82974B2CA4 for ; Thu, 3 Sep 2026 14:12:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.127.231.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788444791; cv=none; b=az9o9Vr5DcrRZHHssUXFBZrCdH91iK0CWU74EQuQPkGebRvRHxUKLHNPf0JYQZDYWDTxZBlgtUtrrqftfVYSCVDtzdVEsapMUkzKbf6eJTN/tLIt03JjcbT/HrDNYQo2O9MpB+Kh0H86slM53hbLeb6vhylNQdAHAWKx5S0p0ZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788444791; c=relaxed/simple; bh=puSA5liMU6OpiwuG3Ma1tWEIw4biXvPc5legy2szouk=; h=From:Mime-Version:Date:Content-Type:To:Cc:Subject:Message-Id; b=RXwcZG0dAowM5omBVxN5pWwxaB1c+BzrO1+NTdL+W5TPKe+XrwS75FhEa+x9QGayXhg4JAe9zwmUDMccBrRHqFlrIJvoiNweGmzxfMmGtWu+ToMrG/5+KNdkppqThM1UrjFECKNgRxtw3mkRq34N/dtOpsKP9zLggcHhfNziDvw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=moonshot.ai; spf=pass smtp.mailfrom=moonshot.ai; dkim=pass (2048-bit key) header.d=moonshot.ai header.i=@moonshot.ai header.b=FPFXknmN; arc=none smtp.client-ip=209.127.231.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=moonshot.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=moonshot.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=moonshot.ai header.i=@moonshot.ai header.b="FPFXknmN" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2510091218; d=moonshot.ai; t=1788444764; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=g3dTl09kOzRbhIjm5SK5uaKZxMYR1BcThZlmWS3SkPY=; b=FPFXknmNh0MZNPekFcRZaXKDsmcAWmPh1ZKPDl7o9saV5FUdG4khV9CjvBpztEgPuWK9ZE 5xKtOgSX76BDGBp6pYyTlGiuhpsFGWEYT5VWdAKomf1HRGU6qwrei4fj/yHidYyaYLGZmp oo/JqdZejFgEi3SV9pyMW7fD3b74AN9dIuYHLjqvbLYSx8HmDUz/4oRMSJuJ2nbYJS6l3g VWftcKvWE4DBobIVVgggt0j/HRBFJA1sNN9skFLZ8rJto81PVEVnTX7QjEMTv/r/J7tq0d 2KbApi5x9q4UhApXdvaAJOA+I7LQm1Hj1lf30DxcH8Cwb5G7eAo2jM+rhiEamw== From: "Yilin Zhang" Content-Transfer-Encoding: quoted-printable X-Lms-Return-Path: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Received: from dev.msh-dev.svc.cluster.local ([117.157.206.135]) by smtp.feishu.cn with ESMTPS; Thu, 03 Sep 2026 22:12:42 +0800 Date: Thu, 3 Sep 2026 22:12:03 +0800 To: "Eric Dumazet" , "Jakub Kicinski" , "Paolo Abeni" Cc: "Yilin Zhang" , , , , "Kimi Security Team" , "Weiming Shi" Subject: [PATCH] inet: frags: invalidate queues before flushing them Message-Id: <20260903141204.40934-1-yilinzhang@moonshot.ai> X-Mailer: git-send-email 2.34.1 X-Original-From: Yilin Zhang Content-Type: text/plain; charset="utf-8" fqdir_pre_exit() flushes the skbs from incomplete queues without changing their completion state. A fragment which found a queue before high_thresh was cleared can then acquire the queue lock and reuse stale reassembly metadata. For IPv6, this can make ip6_frag_reasm() use the old nhoffset with a new skb and access memory out of bounds. The resulting heap corruption can be leveraged for local privilege escalation when unprivileged network namespaces are available. Kill each queue before flushing it in fqdir_pre_exit(). This marks the queue complete and releases any timer reference removed by inet_frag_kill(), while leaving the hash reference for the asynchronous fqdir teardown. In-flight fragments consequently take the existing complete-queue drop path without changing the reusable-queue semantics of inet_frag_queue_flush(). KASAN report: BUG: KASAN: slab-out-of-bounds in ipv6_frag_rcv (net/ipv6/reassembly.c:28= 9 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/re= assembly.c:391 (discriminator 2)) Write of size 1 at addr ff110001039c6e00 by task poc/771 Call Trace: ? ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/rea= ssembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2)) ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reass= embly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2)) ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:479 (discriminator 5)) ip6_input_finish (net/ipv6/ip6_input.c:534) ipv6_rcv (include/net/dst.h:480 (discriminator 3) net/ipv6/ip6_input.c:11= 9 (discriminator 3) net/ipv6/ip6_input.c:109 (discriminator 3) include/linu= x/netfilter.h:325 (discriminator 3) include/linux/netfilter.h:319 (discrimi= nator 3) net/ipv6/ip6_input.c:351 (discriminator 3)) packet_sendmsg (net/packet/af_packet.c:3110 net/packet/af_packet.c:3142) __x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880) The buggy address belongs to the object at ff110001039c6b40 which belongs to the cache skbuff_small_head of size 704 The buggy address is located 0 bytes to the right of allocated 704-byte region [ff110001039c6b40, ff110001039c6e00) BUG: KASAN: slab-out-of-bounds in ip6_protocol_deliver_rcu (net/ipv6/ip6_= input.c:423 (discriminator 1)) Read of size 1 at addr ff110001039c6e08 by task poc/771 Call Trace: ? ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1)) ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1)) ip6_input_finish (net/ipv6/ip6_input.c:534) ipv6_rcv (include/net/dst.h:480 (discriminator 3) net/ipv6/ip6_input.c:11= 9 (discriminator 3) net/ipv6/ip6_input.c:109 (discriminator 3) include/linu= x/netfilter.h:325 (discriminator 3) include/linux/netfilter.h:319 (discrimi= nator 3) net/ipv6/ip6_input.c:351 (discriminator 3)) packet_sendmsg (net/packet/af_packet.c:3110 net/packet/af_packet.c:3142) __x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880) packet_sendmsg (net/packet/af_packet.c:2959 net/packet/af_packet.c:3053 n= et/packet/af_packet.c:3142) __x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880) The buggy address belongs to the object at ff110001039c6b40 which belongs to the cache skbuff_small_head of size 704 The buggy address is located 8 bytes to the right of allocated 704-byte region [ff110001039c6b40, ff110001039c6e00) Fixes: 006a5035b495 ("inet: frags: flush pending skbs in fqdir_pre_exit()") Cc: stable@vger.kernel.org Reported-by: Kimi Security Team Tested-by: Weiming Shi Signed-off-by: Yilin Zhang Reviewed-by: Eric Dumazet --- net/ipv4/inet_fragment.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -235,15 +235,22 @@ void fqdir_pre_exit(struct fqdir *fqdir) rhashtable_walk_start(&hti); =20 while ((fq =3D rhashtable_walk_next(&hti))) { + int refs =3D 0; + if (IS_ERR(fq)) { if (PTR_ERR(fq) !=3D -EAGAIN) break; continue; } spin_lock_bh(&fq->lock); - if (!(fq->flags & INET_FRAG_COMPLETE)) + if (!(fq->flags & INET_FRAG_COMPLETE)) { + inet_frag_kill(fq, &refs); + } + + if (fq->flags & INET_FRAG_HASH_DEAD) inet_frag_queue_flush(fq, 0); spin_unlock_bh(&fq->lock); + inet_frag_putn(fq, refs); } =20 rhashtable_walk_stop(&hti); --=20 2.43.0