From nobody Wed Jun 10 08:20:39 2026 Received: from mail-pj1-f66.google.com (mail-pj1-f66.google.com [209.85.216.66]) (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 3A55A3E8338 for ; Sat, 16 May 2026 16:28:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778948927; cv=none; b=fdx3/kv2jPcDGaXnSMnPp1h00m2WOw/n86MRRgqgiHfCmUnk1IYtrokfybRfYN1jzRYOthiFIPOuR+I21sgXd4ItsPwu5BTHYQm+Eh68Jg33Zkaz01eZPegTcFfHMIImAaVGk8reEebUv7Z19zwlZXuyNEJwecBLckjxYgIfkpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778948927; c=relaxed/simple; bh=pXzVi05Nvzq7KtcKABClEwFyw7Z7ai29Ibsb5P/+O1w=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=iAHtivYLEz7bl8iv6XKFIxos1jmg1grYGi1QjBhbNhenQ0HeB9ddVVfpaIzu8nXoQ5dGFlLIEmVW0IkLjue3jWiyyYZ37bWJf1w+oeEwCvvMbe7hJG4WAM0KiTZNvqdVR0Ia8Ohjdn3nC1rAgo8j+EEfBqEN+5hmysAUDGhxNSs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PXrDPRPi; arc=none smtp.client-ip=209.85.216.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PXrDPRPi" Received: by mail-pj1-f66.google.com with SMTP id 98e67ed59e1d1-367c26471f5so476148a91.1 for ; Sat, 16 May 2026 09:28:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778948920; x=1779553720; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1X2IDixBF08B3l+TKvtHORswI92gaIf4/K71809VYGg=; b=PXrDPRPirL8aYGbfWgBcZnINvbz84FhY06rrYL24ksUh7yoV4dnNb0cueIm/Jf4vQr C7xlgiKDQNSvGJnRwuXgUewoiQapWwK6O6zFyP+3NCiU0WLt12twSpz9t4rIoK2j6MA8 T4X0Z0YjPNuHtAnpOitb01DWQlWFkeSj+IeayJsKsd6f5IlJthos+IjcL0c0wt5AjLqw pOy6oumLUcuhf2gsAHHNG60D0D6wZv8QYwroiiQBq6lkdxe1/scOT49Zv/FhbP8LQPYA Q4tD/2PsckJLgN7rqmTmYlNcpS6Akc8GuNtKk7NmHMmwoavcaUCttHfhtyO0X1COU3SJ H1Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778948920; x=1779553720; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=1X2IDixBF08B3l+TKvtHORswI92gaIf4/K71809VYGg=; b=Rc0BLy15y/RNlQDweM9tLzqHWFol8Kxk5LL+JCkhE6o2490hrhJJ3oJk3GzPV3wB2F mAh7T4IAsdof8CXwZ3mS+TJi/SEwIHNXVjw0ln2il2YA2cwFFVXrc0IV9ubeip+AjgSe uVaf4Dq4XD6WvjSu2uAEbmJo3TcpHpJZYJH+wxg38gkD6DhbhyPU8BSoxD3cj4qaViuv GCd0H5Gs7zy968S+07QiDCrH/egnfice3NSugDvBoamcWGLRu9g6FjRsYfM4Ut22CWWP F6VMoWqBcrGKizf6TUpQ6ygpx+A+UCrK4fkQpnex7V/2kDJlgjXSr1pbnIxPSjUnohwK PViA== X-Forwarded-Encrypted: i=1; AFNElJ9rg7SUVCsZX7TGtvhkSSgXFBl9Bow2nWd3OaY3CDxWS/vZnaMfr1nRwgTWzBbaV9w7WiPUdXQtBk2D1C8=@vger.kernel.org X-Gm-Message-State: AOJu0Yxy788WgKO1On5xq36soMf/7HFEoptM36vpDlO1LJ+nhV2xAANI qWIhmBOkKKFWk3sCfRKEAn8S0oRw1WWHXYlkN5uqeXnTb4JtQvkt61JE X-Gm-Gg: Acq92OEysWKus1H2N2+Imh2J074Y2tZaJ4+W3IAPTRPnE5XxOyPwkT5mon7RUnepd/J oYdkxbEuaDXcuVdBgj3EM1xiqTspZn+klttKR/GzNAy3HHEZymmaRWonxvPDjm0r8PKmyC7gOMs Y6BJtGouwW0vT31jg71p1oInwxbwptfj4548tx0RMJgleBr/8Kpoq/Xzw5GXe7IzEkBF4E0CKXs h7n9/cOHapoDISWb5Y3kmG0ZG6dAmS1Kzh8MHYDThVqJoC9QXcqsbfTlM/cP077ppeS9ArlyCHT WFfkasya2b8KsnZ8EyjqESBmicOIRRambKI3maZn1HJ3PBmmC6dUC0YHUkSLsKZCFyKJzusmctu 2BX0PJccSBs5MHFNiPWltW+e4fwfjQfZoLGzEa30TDbyi6RCu1A0GZfSuygBsUuXXmSCR+tOV09 M+gmCQY66p5Owj8LfXsskTuhQnOS9HwzI= X-Received: by 2002:a17:903:248:b0:2ba:bfc:76a8 with SMTP id d9443c01a7336-2bd7e8a5f58mr91920005ad.16.1778948920198; Sat, 16 May 2026 09:28:40 -0700 (PDT) Received: from localhost ([111.228.63.84]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2bd5bd5ef27sm122916815ad.8.2026.05.16.09.28.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 May 2026 09:28:39 -0700 (PDT) From: Zhang Cen To: Jamal Hadi Salim , Jiri Pirko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, zerocling0077@gmail.com, 2045gemini@gmail.com, Zhang Cen , stable@vger.kernel.org Subject: [PATCH] net/sched: act_pedit: extend the writable skb range per key Date: Sun, 17 May 2026 00:28:25 +0800 Message-Id: <20260516162825.1480113-1-rollkingzzc@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" tcf_pedit_act() builds a rough writable prefix from tcfp_off_max_hint before the action mutates any packet bytes. Since 6c02568fd1ae, TCP and UDP keys recompute their L4 base from the current L3 header inside the key loop. An earlier key can therefore change a later header-relative base and make the final store land outside the initially ensured prefix, where it can fall back to skb_store_bits() on skb frags. Keep the initial estimate as a fast path, but grow the ensured writable range from each key's final computed write offset before loading or storing the edited word. Fixes: 6c02568fd1ae ("net/sched: act_pedit: Parse L3 Header for L4 offset") Cc: stable@vger.kernel.org Co-developed-by: Han Guidong <2045gemini@gmail.com> Signed-off-by: Han Guidong <2045gemini@gmail.com> Signed-off-by: Zhang Cen --- While researching recent page cache bugs, we discovered this bug. We confir= med it allows overwriting the page cache of read-only files via splice(). W= e haven't attempted to write an exploit, but the corruption primitive is ve= rified. PoC available upon request. Recommend fixing ASAP. --- net/sched/act_pedit.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index bc20f08a27890..58a8eae6d43e7 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -398,11 +398,12 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *s= kb, =20 parms =3D rcu_dereference_bh(p->parms); =20 - max_offset =3D (skb_transport_header_was_set(skb) ? - skb_transport_offset(skb) : - skb_network_offset(skb)) + - parms->tcfp_off_max_hint; - if (skb_ensure_writable(skb, min(skb->len, max_offset))) + max_offset =3D min_t(u32, skb->len, + (skb_transport_header_was_set(skb) ? + skb_transport_offset(skb) : + skb_network_offset(skb)) + + parms->tcfp_off_max_hint); + if (skb_ensure_writable(skb, max_offset)) goto done; =20 tcf_lastuse_update(&p->tcf_tm); @@ -414,8 +415,9 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, for (i =3D parms->tcfp_nkeys; i > 0; i--, tkey++) { int offset =3D tkey->off; int hoffset =3D 0; + int write_offset; u32 *ptr, hdata; - u32 val; + u32 val, write_end; int rc; =20 if (tkey_ex) { @@ -451,12 +453,26 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *s= kb, } } =20 - if (!offset_valid(skb, hoffset + offset)) { - pr_info_ratelimited("tc action pedit offset %d out of bounds\n", hoffse= t + offset); + write_offset =3D hoffset + offset; + if (!offset_valid(skb, write_offset)) { + pr_info_ratelimited("tc action pedit offset %d out of bounds\n", + write_offset); goto bad; } =20 - ptr =3D skb_header_pointer(skb, hoffset + offset, + /* Earlier edits can change later header-relative offsets, so + * grow the writable window from the final per-key store. + */ + if (write_offset >=3D 0) { + write_end =3D (u32)write_offset + sizeof(hdata); + if (write_end > max_offset) { + max_offset =3D min_t(u32, skb->len, write_end); + if (skb_ensure_writable(skb, max_offset)) + goto bad; + } + } + + ptr =3D skb_header_pointer(skb, write_offset, sizeof(hdata), &hdata); if (!ptr) goto bad; @@ -475,7 +491,7 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, =20 *ptr =3D ((*ptr & tkey->mask) ^ val); if (ptr =3D=3D &hdata) - skb_store_bits(skb, hoffset + offset, ptr, 4); + skb_store_bits(skb, write_offset, ptr, sizeof(hdata)); } =20 goto done; --=20 2.43.0