From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f196.google.com (mail-pl1-f196.google.com [209.85.214.196]) (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 8C5113E715C for ; Sat, 16 May 2026 16:28:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.196 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778948928; cv=none; b=kGHOSTjiiSH/nq5AX0YvryodDGMTCM91/3skfKnytRAdBt4bEvYx6C2hOQw0S8gfEmyXOHv+DXkqnTtO+bZ/pNnxv4ycwbsfYRObfPiXxu99CqAK6tgwcwIBjOv5XD5hZJHxhXcBzNzovBCKiBce50BqnJjdRq2YVSJpadrYFWo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778948928; c=relaxed/simple; bh=pXzVi05Nvzq7KtcKABClEwFyw7Z7ai29Ibsb5P/+O1w=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=gkpBFAihjzRL8tEonhZePTpf+foN5DW1l2P6+xhnLi9qhpVVPxkTVoUDFc766KuPsmgQecdxzgSi4ZMLhWTbIHeTNMYHCoXqhdmydvjF176H04BFmpDj+SymJl+EagTxJCUVpreuMIK8MQNDBD4IfVMrWYFW6tPCbWCn4Tmq1yc= 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.214.196 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-pl1-f196.google.com with SMTP id d9443c01a7336-2ba6485d219so5874255ad.3 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=sQnq9dwzyWxku43QpXACvq1bFSdWmoMlngyEOKAv6vQ/3/MuRp4fDG6p9Ky6E6BN41 r2G2rvtKFn6EtoP2HUacip6FUgpcZuMGzvW5ZIONrWC0I57J42ORx61jEs1GLQfU8LlG IbVA0dk9b8g0iPVopiiOa6XxievGmRAq/lMm+8Kp8C3XkhE5JxD49sqZ4FeQ95EfcOSp o67IPEclhUeOOZoOSOFBHv7qzmlSmGBRerBeCI5FQq18sDoRld42vwVMRN7DxwPSyOlS 4AYLNQ/ZUME+yVuaoU5U0DZhQoSpzZinQifoqGDZOToJKqOIuuShJFcU9b0IlysHuSlY t7Cw== X-Gm-Message-State: AOJu0YwWrydcFbayFcdxOhIN72TYmgvQsoun88fol+nheFJVbvP6ArUS HjgyNxHS29PJJL1K1IZ1D4pNUX9AuBlZ2HCnqvnDOJFf7Ogwds0Whf3b X-Gm-Gg: Acq92OGE9FoRAhk28N2914gVlG5uIShOiNSnmptiLZtLaSJPnvLbp8aVP3piMVs40Nk GtNvdnphH6Gp8xVQSqge2Z2qWc4oTBGeFTBuxDnhJZ0pjj6EHuWNtBszsESpR9aWl6S+3iaIo5L 995oMwYK2fyjv1Th+b/DsdvqxMiTCwGUskpSIDzCFFbeYjsqJPVDQbjbG+S+prl7Rz4AgWPWQxK PLXlmf0olTGVE11l4+taOQfq9uIca4owDhVmR5mqXBItmgXwgZNXiTOU9czU8Z59H1ERFLg6x07 YE/DFJxxiklczHnB6Athy12vhR7hG2jnGexroN8ks/H8O+opG5+w/qXhzjggJlyVq943Z/Pc3zj LTyKOFuE/Z5l6ZBaZx9DsqH47RX34Xi2GlC5v8uCBx0NR5o+Yfhf003fG7w1eZm9r39lgVNIvmz ydWyfAFOITWVIifndRwyCRFfec8OJbdis= 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: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 confirmed it allows overwriting the page cache of read-only files via splice(). We haven't attempted to write an exploit, but the corruption primitive is verified. 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 *skb, parms = rcu_dereference_bh(p->parms); - max_offset = (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 = 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; tcf_lastuse_update(&p->tcf_tm); @@ -414,8 +415,9 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) { int offset = tkey->off; int hoffset = 0; + int write_offset; u32 *ptr, hdata; - u32 val; + u32 val, write_end; int rc; if (tkey_ex) { @@ -451,12 +453,26 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, } } - if (!offset_valid(skb, hoffset + offset)) { - pr_info_ratelimited("tc action pedit offset %d out of bounds\n", hoffset + offset); + write_offset = hoffset + offset; + if (!offset_valid(skb, write_offset)) { + pr_info_ratelimited("tc action pedit offset %d out of bounds\n", + write_offset); goto bad; } - ptr = 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 >= 0) { + write_end = (u32)write_offset + sizeof(hdata); + if (write_end > max_offset) { + max_offset = min_t(u32, skb->len, write_end); + if (skb_ensure_writable(skb, max_offset)) + goto bad; + } + } + + ptr = 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, *ptr = ((*ptr & tkey->mask) ^ val); if (ptr == &hdata) - skb_store_bits(skb, hoffset + offset, ptr, 4); + skb_store_bits(skb, write_offset, ptr, sizeof(hdata)); } goto done; -- 2.43.0