* [LTP] [PATCH v5 0/4] Reproducer for cve-2026-46331
@ 2026-07-14 8:38 Andrea Cervesato
2026-07-14 8:38 ` [LTP] [PATCH v5 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Andrea Cervesato @ 2026-07-14 8:38 UTC (permalink / raw)
To: Linux Test Project
tst_kconfig.c:90: TINFO: Parsing kernel config '/lib/modules/7.1.0-rc5-virtme/build/.config'
tst_tmpdir.c:308: TINFO: Using /tmp/LTP_cveTzmFu2 as tmpdir (overlayfs filesystem)
tst_test.c:2047: TINFO: LTP version: 20260529-80-g0b891ea23
tst_test.c:2050: TINFO: Tested kernel: 7.1.0-rc5-virtme #9 SMP PREEMPT_DYNAMIC Mon Jul 6 14:50:05 CEST 2026 x86_64
tst_kconfig.c:90: TINFO: Parsing kernel config '/lib/modules/7.1.0-rc5-virtme/build/.config'
tst_test.c:1875: TINFO: Overall timeout per run is 0h 00m 30s
cve-2026-46331.c:221: TFAIL: Page cache corrupted via act_pedit partial COW bypass
HINT: You _MAY_ be missing kernel fixes:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=899ee91156e5
HINT: You _MAY_ be vulnerable to CVE(s):
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-46331
Summary:
passed 0
failed 1
broken 0
skipped 0
warnings 0
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Changes in v5:
- set fd to -1
- better macro documentation
- Link to v4: https://lore.kernel.org/20260713-cve-2026-46331-v4-0-0089fd01ce62@suse.com
Changes in v4:
- fix enum definition
- define NETDEV_MAY_REMOVE_QDISC
- Link to v3: https://lore.kernel.org/20260707-cve-2026-46331-v3-0-3f6f1d697eec@suse.com
Changes in v3:
- fix build failure in opensuse 42.2
- Link to v2: https://lore.kernel.org/20260706-cve-2026-46331-v2-0-d5e47a113a84@suse.com
Changes in v2:
- remove sleep()
- Link to v1: https://lore.kernel.org/20260706-cve-2026-46331-v1-0-c55d45f022d1@suse.com
---
Andrea Cervesato (4):
lapi: Add pkt_cls.h fallback
lapi: Add pkt_sched.h fallback
lapi: Add tc_pedit.h fallback
cve: Add act_pedit page-cache corruption test
configure.ac | 6 +
include/lapi/pkt_cls.h | 19 +++
include/lapi/pkt_sched.h | 19 +++
include/lapi/tc_pedit.h | 52 ++++++++
include/tst_netdevice.h | 7 ++
runtest/cve | 1 +
testcases/cve/.gitignore | 1 +
testcases/cve/cve-2026-46331.c | 274 +++++++++++++++++++++++++++++++++++++++++
8 files changed, 379 insertions(+)
---
base-commit: 7ca5dc366a558f3666223e6abe579edd90bafd38
change-id: 20260706-cve-2026-46331-434f99cf2c61
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread* [LTP] [PATCH v5 1/4] lapi: Add pkt_cls.h fallback 2026-07-14 8:38 [LTP] [PATCH v5 0/4] Reproducer for cve-2026-46331 Andrea Cervesato @ 2026-07-14 8:38 ` Andrea Cervesato 2026-07-14 10:53 ` [LTP] " linuxtestproject.agent 2026-07-14 8:38 ` [LTP] [PATCH v5 2/4] lapi: Add pkt_sched.h fallback Andrea Cervesato ` (2 subsequent siblings) 3 siblings, 1 reply; 9+ messages in thread From: Andrea Cervesato @ 2026-07-14 8:38 UTC (permalink / raw) To: Linux Test Project From: Andrea Cervesato <andrea.cervesato@suse.com> Reviewed-by: Petr Vorel <pvorel@suse.cz> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- include/lapi/pkt_cls.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/lapi/pkt_cls.h b/include/lapi/pkt_cls.h new file mode 100644 index 0000000000000000000000000000000000000000..b7a6278f07e6fcedcb7c412e833cb01170f24f74 --- /dev/null +++ b/include/lapi/pkt_cls.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +#ifndef LAPI_PKT_CLS_H__ +#define LAPI_PKT_CLS_H__ + +#include <linux/pkt_cls.h> + +#ifndef TC_ACT_PIPE +# define TC_ACT_PIPE 3 +#endif + +#ifndef TCA_MATCHALL_ACT +# define TCA_MATCHALL_ACT 2 +#endif + +#endif /* LAPI_PKT_CLS_H__ */ -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [LTP] lapi: Add pkt_cls.h fallback 2026-07-14 8:38 ` [LTP] [PATCH v5 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato @ 2026-07-14 10:53 ` linuxtestproject.agent 0 siblings, 0 replies; 9+ messages in thread From: linuxtestproject.agent @ 2026-07-14 10:53 UTC (permalink / raw) To: Andrea Cervesato; +Cc: ltp Hi Andrea, On Tue, 14 Jul 2026 10:38:58 +0200, Andrea Cervesato wrote: > lapi: Add pkt_cls.h fallback --- [PATCH 4/4] --- > +/* > + * Same as NETDEV_REMOVE_QDISC() but does not fail when the qdisc is > + * missing (strict=0), so it can be used to clear a possibly absent qdisc. > + */ > +#define NETDEV_MAY_REMOVE_QDISC(ifname, family, parent, handle, qd_kind) \ New public macros in include/ require kernel-doc (/** */), not a plain block comment. The content is fine; it just needs the right opener: /** * NETDEV_MAY_REMOVE_QDISC - remove qdisc without failing if absent. * @ifname: network interface name * @family: address family * @parent: parent handle * @handle: qdisc handle * @qd_kind: qdisc kind string * * Same as NETDEV_REMOVE_QDISC() but passes strict=0, so it does not * fail when the qdisc is missing. */ > +#define NETDEV_REMOVE_QDISC(ifname, family, parent, handle, qd_kind) \ > tst_netdev_remove_qdisc(__FILE__, __LINE__, 1, (ifname), (family), \ > (parent), (handle), (qd_kind)) > +/* No blank line between the closing of NETDEV_REMOVE_QDISC and the comment that opens NETDEV_MAY_REMOVE_QDISC. All other macro blocks in the file have a blank line between them. Verdict - Needs revision --- Note: The agent can sometimes produce false positives although often its findings are genuine. If you find issues with the review, please comment this email or ignore the suggestions. Regards, LTP AI Reviewer -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 9+ messages in thread
* [LTP] [PATCH v5 2/4] lapi: Add pkt_sched.h fallback 2026-07-14 8:38 [LTP] [PATCH v5 0/4] Reproducer for cve-2026-46331 Andrea Cervesato 2026-07-14 8:38 ` [LTP] [PATCH v5 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato @ 2026-07-14 8:38 ` Andrea Cervesato 2026-07-14 8:39 ` [LTP] [PATCH v5 3/4] lapi: Add tc_pedit.h fallback Andrea Cervesato 2026-07-14 8:39 ` [LTP] [PATCH v5 4/4] cve: Add act_pedit page-cache corruption test Andrea Cervesato 3 siblings, 0 replies; 9+ messages in thread From: Andrea Cervesato @ 2026-07-14 8:38 UTC (permalink / raw) To: Linux Test Project From: Andrea Cervesato <andrea.cervesato@suse.com> Reviewed-by: Petr Vorel <pvorel@suse.cz> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- include/lapi/pkt_sched.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/lapi/pkt_sched.h b/include/lapi/pkt_sched.h new file mode 100644 index 0000000000000000000000000000000000000000..4d7b2860df4a478214385f248995361f6f1cf282 --- /dev/null +++ b/include/lapi/pkt_sched.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +#ifndef LAPI_PKT_SCHED_H__ +#define LAPI_PKT_SCHED_H__ + +#include <linux/pkt_sched.h> + +#ifndef TC_H_CLSACT +# define TC_H_CLSACT TC_H_INGRESS +#endif + +#ifndef TC_H_MIN_EGRESS +# define TC_H_MIN_EGRESS 0xFFF3U +#endif + +#endif /* LAPI_PKT_SCHED_H__ */ -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [LTP] [PATCH v5 3/4] lapi: Add tc_pedit.h fallback 2026-07-14 8:38 [LTP] [PATCH v5 0/4] Reproducer for cve-2026-46331 Andrea Cervesato 2026-07-14 8:38 ` [LTP] [PATCH v5 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato 2026-07-14 8:38 ` [LTP] [PATCH v5 2/4] lapi: Add pkt_sched.h fallback Andrea Cervesato @ 2026-07-14 8:39 ` Andrea Cervesato 2026-07-14 8:39 ` [LTP] [PATCH v5 4/4] cve: Add act_pedit page-cache corruption test Andrea Cervesato 3 siblings, 0 replies; 9+ messages in thread From: Andrea Cervesato @ 2026-07-14 8:39 UTC (permalink / raw) To: Linux Test Project From: Andrea Cervesato <andrea.cervesato@suse.com> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- configure.ac | 6 ++++++ include/lapi/tc_pedit.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/configure.ac b/configure.ac index 3a1283ac3a30d85ca731ca54a281ed0c1d4bc06e..19fc5e1b8f5f5f94bd797ff2ba4275c29c20cb6c 100644 --- a/configure.ac +++ b/configure.ac @@ -190,6 +190,12 @@ AC_CHECK_MEMBERS([struct utsname.domainname],,,[ ]) AC_CHECK_TYPES([enum kcmp_type],,,[#include <linux/kcmp.h>]) +AC_CHECK_TYPES([enum pedit_header_type],,,[#include <linux/tc_act/tc_pedit.h>]) +AC_CHECK_TYPES([enum pedit_cmd],,,[#include <linux/tc_act/tc_pedit.h>]) +AC_CHECK_DECLS([TCA_PEDIT_PARMS_EX, TCA_PEDIT_KEYS_EX, TCA_PEDIT_KEY_EX, + TCA_PEDIT_KEY_EX_HTYPE, TCA_PEDIT_KEY_EX_CMD],,,[ +#include <linux/tc_act/tc_pedit.h> +]) AC_CHECK_TYPES([struct acct_v3],,,[#include <sys/acct.h>]) AC_CHECK_TYPES([struct af_alg_iv, struct sockaddr_alg],,,[# include <linux/if_alg.h>]) AC_CHECK_TYPES([struct clone_args],,,[#include <sched.h>]) diff --git a/include/lapi/tc_pedit.h b/include/lapi/tc_pedit.h new file mode 100644 index 0000000000000000000000000000000000000000..057d96efd3fb0f2556886c9774b0bd5682b14398 --- /dev/null +++ b/include/lapi/tc_pedit.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 SUSE LLC <andrea.cervesato@suse.com> + */ + +#ifndef LAPI_TC_PEDIT_H__ +#define LAPI_TC_PEDIT_H__ + +#include "config.h" +#include <linux/tc_act/tc_pedit.h> + +#if !HAVE_DECL_TCA_PEDIT_PARMS_EX +# define TCA_PEDIT_PARMS_EX 4 +#endif + +#if !HAVE_DECL_TCA_PEDIT_KEYS_EX +# define TCA_PEDIT_KEYS_EX 5 +#endif + +#if !HAVE_DECL_TCA_PEDIT_KEY_EX +# define TCA_PEDIT_KEY_EX 6 +#endif + +#if !HAVE_DECL_TCA_PEDIT_KEY_EX_HTYPE +# define TCA_PEDIT_KEY_EX_HTYPE 1 +#endif + +#if !HAVE_DECL_TCA_PEDIT_KEY_EX_CMD +# define TCA_PEDIT_KEY_EX_CMD 2 +#endif + +#ifndef HAVE_ENUM_PEDIT_HEADER_TYPE +enum pedit_header_type { + TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK = 0, + TCA_PEDIT_KEY_EX_HDR_TYPE_ETH, + TCA_PEDIT_KEY_EX_HDR_TYPE_IP4, + TCA_PEDIT_KEY_EX_HDR_TYPE_IP6, + TCA_PEDIT_KEY_EX_HDR_TYPE_TCP, + TCA_PEDIT_KEY_EX_HDR_TYPE_UDP, + __PEDIT_HDR_TYPE_MAX, +}; +#endif + +#ifndef HAVE_ENUM_PEDIT_CMD +enum pedit_cmd { + TCA_PEDIT_KEY_EX_CMD_SET = 0, + TCA_PEDIT_KEY_EX_CMD_ADD, + __PEDIT_CMD_MAX, +}; +#endif + +#endif /* LAPI_TC_PEDIT_H__ */ -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [LTP] [PATCH v5 4/4] cve: Add act_pedit page-cache corruption test 2026-07-14 8:38 [LTP] [PATCH v5 0/4] Reproducer for cve-2026-46331 Andrea Cervesato ` (2 preceding siblings ...) 2026-07-14 8:39 ` [LTP] [PATCH v5 3/4] lapi: Add tc_pedit.h fallback Andrea Cervesato @ 2026-07-14 8:39 ` Andrea Cervesato 3 siblings, 0 replies; 9+ messages in thread From: Andrea Cervesato @ 2026-07-14 8:39 UTC (permalink / raw) To: Linux Test Project From: Andrea Cervesato <andrea.cervesato@suse.com> Regression test for CVE-2026-46331. The act_pedit action computed a stale COW range, letting a TCP-typed key write past it into page-cache pages placed in the skb by sendfile. Reviewed-by: Cyril Hrubis <chrubis@suse.cz> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- include/tst_netdevice.h | 7 ++ runtest/cve | 1 + testcases/cve/.gitignore | 1 + testcases/cve/cve-2026-46331.c | 274 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 283 insertions(+) diff --git a/include/tst_netdevice.h b/include/tst_netdevice.h index 2394f9c7fd6f58cd390ac38e3426858ffe402f1f..2617bb149cf7409e2ca7be00a6442f35a260551e 100644 --- a/include/tst_netdevice.h +++ b/include/tst_netdevice.h @@ -146,6 +146,13 @@ int tst_netdev_remove_qdisc(const char *file, const int lineno, int strict, #define NETDEV_REMOVE_QDISC(ifname, family, parent, handle, qd_kind) \ tst_netdev_remove_qdisc(__FILE__, __LINE__, 1, (ifname), (family), \ (parent), (handle), (qd_kind)) +/* + * Same as NETDEV_REMOVE_QDISC() but does not fail when the qdisc is + * missing (strict=0), so it can be used to clear a possibly absent qdisc. + */ +#define NETDEV_MAY_REMOVE_QDISC(ifname, family, parent, handle, qd_kind) \ + tst_netdev_remove_qdisc(__FILE__, __LINE__, 0, (ifname), (family), \ + (parent), (handle), (qd_kind)) /* * Add traffic class to queueing discipline. Network interface name is diff --git a/runtest/cve b/runtest/cve index 27e12e0c1536fc479471ef4fcc7a461834c57398..3bbcfd6a2f2fb204fc6ae4ba89b5a7554c2fcbc5 100644 --- a/runtest/cve +++ b/runtest/cve @@ -99,3 +99,4 @@ cve-2026-43284 xfrm01 cve-2026-43494 io_uring04 cve-2026-46300 xfrm02 cve-2026-46300-skb-segment xfrm03 +cve-2026-46331 cve-2026-46331 diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore index dc1dad5b0d0d02a3ab57e72516c33ee7949c8431..bc1af0dd2c8086e4f5f78a3b15b91fafbd8f5936 100644 --- a/testcases/cve/.gitignore +++ b/testcases/cve/.gitignore @@ -15,3 +15,4 @@ icmp_rate_limit01 tcindex01 cve-2025-38236 cve-2025-21756 +cve-2026-46331 diff --git a/testcases/cve/cve-2026-46331.c b/testcases/cve/cve-2026-46331.c new file mode 100644 index 0000000000000000000000000000000000000000..c33d358396f21024d8a68e9cd5c4cae0a9339a9f --- /dev/null +++ b/testcases/cve/cve-2026-46331.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +/*\ + * Verify that the ``act_pedit`` traffic-control action correctly COW's + * all modified regions of an skb before writing, so that page-cache + * pages referenced via :manpage:`sendfile(2)` are not corrupted. + * + * ``tcf_pedit_act()`` computed the COW range for + * ``skb_ensure_writable()`` once before the key loop using + * ``tcfp_off_max_hint``, but the hint did not account for the runtime + * header offset added by typed keys. An egress pedit rule whose first + * ``NETWORK`` key inflates the IP header length (IHL 15) pushes + * subsequent ``TCP``-typed key writes past the stale COW boundary, + * allowing them to scribble directly into page-cache pages that + * :manpage:`sendfile(2)` placed in the skb. + * + * [Algorithm] + * + * - Create a 4 KiB file with a sequential byte pattern and set its + * permissions to read-only (0444) + * - Reopen the file ``O_RDONLY`` + * - Add a ``clsact`` qdisc on ``lo`` and establish a TCP connection + * on loopback + * - After the handshake, install a ``matchall`` egress filter carrying + * a two-key pedit action: key 0 sets IP IHL to 15 (NETWORK type), + * key 1 writes a 4-byte marker at TCP-relative offset 512 + * - :manpage:`sendfile(2)` the file through the TCP socket so the + * pedit action fires on the page-cache-backed skb + * - Reread the file through the same ``O_RDONLY`` descriptor and + * compare with the original pattern; any difference means the + * page cache was corrupted + */ + +#include <sys/sendfile.h> +#include <linux/rtnetlink.h> + +#include "tst_test.h" +#include "tst_net.h" +#include "tst_netdevice.h" +#include "lapi/if_ether.h" +#include "lapi/pkt_sched.h" +#include "lapi/pkt_cls.h" +#include "lapi/tc_pedit.h" +#include "lapi/sched.h" +#include "lapi/tcp.h" + +#define TESTFILE "pagecache_test" +#define DATA_SIZE 4096 +#define PORT 4445 + +#define NKEYS 2 +#define IHL_VALUE 0x4fu /* IP version 4, IHL 15 (max) */ +#define IHL_MASK 0xffffff00u /* keep TOS / tot_len bytes */ +#define MARKER_OFFSET 512 /* TCP-relative key offset */ +#define MARKER_VALUE 0xccccccccu /* 4-byte marker written by pedit */ + +/* + * Pedit selector buffer: struct tc_pedit_sel followed by NKEYS keys. + * sizeof(struct tc_pedit_sel) does not include the flexible array, so + * the trailing keys[] array provides storage for it. + */ +static struct { + struct tc_pedit_sel sel; + struct tc_pedit_key keys[NKEYS]; +} pedit_sel_buf; + +/* --- Nested attribute lists for the matchall + pedit filter config --- */ + +static uint16_t key0_htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; +static uint16_t key0_cmd = TCA_PEDIT_KEY_EX_CMD_SET; +static uint16_t key1_htype = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP; +static uint16_t key1_cmd = TCA_PEDIT_KEY_EX_CMD_SET; + +static const struct tst_netlink_attr_list key0_ex[] = { + {TCA_PEDIT_KEY_EX_HTYPE, &key0_htype, sizeof(key0_htype), NULL}, + {TCA_PEDIT_KEY_EX_CMD, &key0_cmd, sizeof(key0_cmd), NULL}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list key1_ex[] = { + {TCA_PEDIT_KEY_EX_HTYPE, &key1_htype, sizeof(key1_htype), NULL}, + {TCA_PEDIT_KEY_EX_CMD, &key1_cmd, sizeof(key1_cmd), NULL}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list keys_ex[] = { + {TCA_PEDIT_KEY_EX, NULL, 0, key0_ex}, + {TCA_PEDIT_KEY_EX, NULL, 0, key1_ex}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list pedit_opts[] = { + {TCA_PEDIT_PARMS_EX, &pedit_sel_buf, sizeof(pedit_sel_buf), NULL}, + {TCA_PEDIT_KEYS_EX, NULL, 0, keys_ex}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list action_entry[] = { + {TCA_ACT_KIND, "pedit", sizeof("pedit"), NULL}, + {TCA_ACT_OPTIONS, NULL, 0, pedit_opts}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list action_list[] = { + {1, NULL, 0, action_entry}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list matchall_opts[] = { + {TCA_MATCHALL_ACT, NULL, 0, action_list}, + {0, NULL, -1, NULL} +}; + +static const struct tst_netlink_attr_list filter_config[] = { + {TCA_OPTIONS, NULL, 0, matchall_opts}, + {0, NULL, -1, NULL} +}; + +static uint8_t original[DATA_SIZE]; +static int file_fd = -1; +static int listen_fd = -1; +static int cli_fd = -1; +static int acc_fd = -1; + +static void setup(void) +{ + struct sockaddr_in addr; + int i; + + tst_setup_netns(); + NETDEV_SET_STATE("lo", 1); + + listen_fd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0); + SAFE_SETSOCKOPT_INT(listen_fd, SOL_SOCKET, SO_REUSEADDR, 1); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(PORT); + + SAFE_BIND(listen_fd, (struct sockaddr *)&addr, sizeof(addr)); + SAFE_LISTEN(listen_fd, 1); + + for (i = 0; i < DATA_SIZE; i++) + original[i] = (uint8_t)(i & 0xff); + + memset(&pedit_sel_buf, 0, sizeof(pedit_sel_buf)); + pedit_sel_buf.sel.nkeys = NKEYS; + pedit_sel_buf.sel.action = TC_ACT_PIPE; + + /* Key 0: inflate IP IHL to 15 (push TCP header offset to 60) */ + pedit_sel_buf.keys[0].off = 0; + pedit_sel_buf.keys[0].val = IHL_VALUE; + pedit_sel_buf.keys[0].mask = IHL_MASK; + + /* Key 1: write marker via TCP-typed offset (past stale COW) */ + pedit_sel_buf.keys[1].off = MARKER_OFFSET; + pedit_sel_buf.keys[1].val = MARKER_VALUE; + pedit_sel_buf.keys[1].mask = 0; +} + +static void run(void) +{ + struct sockaddr_in addr; + uint8_t readback[DATA_SIZE]; + off_t off = 0; + int wr_fd; + + wr_fd = SAFE_OPEN(TESTFILE, O_WRONLY | O_CREAT, 0444); + SAFE_WRITE(SAFE_WRITE_ALL, wr_fd, original, DATA_SIZE); + SAFE_CLOSE(wr_fd); + + file_fd = SAFE_OPEN(TESTFILE, O_RDONLY); + + /* + * Clean-slate clsact qdisc so no filter is active during the + * TCP handshake (the IHL-inflating key would corrupt SYN/ACK). + */ + NETDEV_MAY_REMOVE_QDISC("lo", AF_UNSPEC, TC_H_CLSACT, + TC_H_MAKE(TC_H_CLSACT, 0), "clsact"); + NETDEV_ADD_QDISC("lo", AF_UNSPEC, TC_H_CLSACT, + TC_H_MAKE(TC_H_CLSACT, 0), "clsact", NULL); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(PORT); + + cli_fd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0); + SAFE_CONNECT(cli_fd, (struct sockaddr *)&addr, sizeof(addr)); + acc_fd = SAFE_ACCEPT(listen_fd, NULL, NULL); + + /* Arm the pedit filter AFTER the handshake completes */ + NETDEV_ADD_TRAFFIC_FILTER("lo", + TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS), + 0, ETH_P_ALL, 1, "matchall", + filter_config); + + SAFE_SETSOCKOPT_INT(cli_fd, IPPROTO_TCP, TCP_NODELAY, 1); + + /* + * sendfile places page-cache pages in the skb. With + * TCP_NODELAY the 4 KiB payload fits a single segment whose + * egress path -- including the pedit action -- completes + * synchronously inside dev_queue_xmit on loopback. + */ + if (sendfile(cli_fd, file_fd, &off, DATA_SIZE) < 0) + tst_brk(TBROK | TERRNO, "sendfile() failed"); + + SAFE_CLOSE(cli_fd); + cli_fd = -1; + SAFE_CLOSE(acc_fd); + acc_fd = -1; + + /* + * Read back through the same O_RDONLY fd that sendfile used. + * sendfile with a non-NULL offset does not change the fd's + * file position, so it is still at 0. Keeping the same fd + * guarantees we hit the same page-cache pages. + */ + SAFE_READ(1, file_fd, readback, sizeof(readback)); + SAFE_CLOSE(file_fd); + file_fd = -1; + + if (memcmp(readback, original, DATA_SIZE) != 0) + tst_res(TFAIL, + "Page cache corrupted via act_pedit partial COW bypass"); + else + tst_res(TPASS, "Page cache was not corrupted"); + + SAFE_UNLINK(TESTFILE); +} + +static void cleanup(void) +{ + if (cli_fd != -1) + SAFE_CLOSE(cli_fd); + + if (acc_fd != -1) + SAFE_CLOSE(acc_fd); + + if (file_fd != -1) + SAFE_CLOSE(file_fd); + + if (listen_fd != -1) + SAFE_CLOSE(listen_fd); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .needs_tmpdir = 1, + .needs_kconfigs = (const char *[]) { + "CONFIG_USER_NS=y", + "CONFIG_NET_NS=y", + "CONFIG_NET_SCH_INGRESS", + "CONFIG_NET_CLS_MATCHALL", + "CONFIG_NET_ACT_PEDIT", + NULL + }, + .save_restore = (const struct tst_path_val[]) { + {PATH_USER_MAX_USER_NAMESPACES, "1024", TST_SR_SKIP}, + {} + }, + .tags = (const struct tst_tag[]) { + {"linux-git", "899ee91156e5"}, + {"CVE", "2026-46331"}, + {} + }, +}; -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [LTP] [PATCH v4 1/4] lapi: Add pkt_cls.h fallback @ 2026-07-13 12:37 Andrea Cervesato 2026-07-13 14:13 ` [LTP] " linuxtestproject.agent 0 siblings, 1 reply; 9+ messages in thread From: Andrea Cervesato @ 2026-07-13 12:37 UTC (permalink / raw) To: Linux Test Project From: Andrea Cervesato <andrea.cervesato@suse.com> Reviewed-by: Petr Vorel <pvorel@suse.cz> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- include/lapi/pkt_cls.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/lapi/pkt_cls.h b/include/lapi/pkt_cls.h new file mode 100644 index 0000000000000000000000000000000000000000..b7a6278f07e6fcedcb7c412e833cb01170f24f74 --- /dev/null +++ b/include/lapi/pkt_cls.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +#ifndef LAPI_PKT_CLS_H__ +#define LAPI_PKT_CLS_H__ + +#include <linux/pkt_cls.h> + +#ifndef TC_ACT_PIPE +# define TC_ACT_PIPE 3 +#endif + +#ifndef TCA_MATCHALL_ACT +# define TCA_MATCHALL_ACT 2 +#endif + +#endif /* LAPI_PKT_CLS_H__ */ -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [LTP] lapi: Add pkt_cls.h fallback 2026-07-13 12:37 [LTP] [PATCH v4 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato @ 2026-07-13 14:13 ` linuxtestproject.agent 0 siblings, 0 replies; 9+ messages in thread From: linuxtestproject.agent @ 2026-07-13 14:13 UTC (permalink / raw) To: Andrea Cervesato; +Cc: ltp Hi Andrea, On Mon, 13 Jul 2026 14:37:07 +0200, Andrea Cervesato wrote: > lapi: Add pkt_cls.h fallback --- [PATCH 4/4] --- > +static int file_fd = -1; > +static int listen_fd = -1; > +static int cli_fd = -1; > +static int acc_fd = -1; > + SAFE_CLOSE(cli_fd); > + SAFE_CLOSE(acc_fd); > + SAFE_CLOSE(file_fd); > + if (cli_fd != -1) > + SAFE_CLOSE(cli_fd); > + > + if (acc_fd != -1) > + SAFE_CLOSE(acc_fd); > + > + if (file_fd != -1) > + SAFE_CLOSE(file_fd); run() closes cli_fd, acc_fd, and file_fd but does not reset them to -1. cleanup() is always called after run() completes, sees non-(-1) values, and calls SAFE_CLOSE() a second time. SAFE_CLOSE() calls tst_brk(TBROK) on EBADF, so the test always ends with TBROK on a clean kernel. Add reset-to-(-1) after each close in run(): SAFE_CLOSE(cli_fd); cli_fd = -1; SAFE_CLOSE(acc_fd); acc_fd = -1; ... SAFE_CLOSE(file_fd); file_fd = -1; > +#define NETDEV_MAY_REMOVE_QDISC(ifname, family, parent, handle, qd_kind) \ > + tst_netdev_remove_qdisc(__FILE__, __LINE__, 0, (ifname), (family), \ > + (parent), (handle), (qd_kind)) The new macro silently tolerates a missing qdisc (strict=0) while the existing NETDEV_REMOVE_QDISC fails hard. A short comment before the definition would clarify that distinction for readers. Verdict - Needs revision --- Note: The agent can sometimes produce false positives although often its findings are genuine. If you find issues with the review, please comment this email or ignore the suggestions. Regards, LTP AI Reviewer -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 9+ messages in thread
* [LTP] [PATCH v3 1/4] lapi: Add pkt_cls.h fallback @ 2026-07-07 13:42 Andrea Cervesato 2026-07-07 14:28 ` [LTP] " linuxtestproject.agent 0 siblings, 1 reply; 9+ messages in thread From: Andrea Cervesato @ 2026-07-07 13:42 UTC (permalink / raw) To: Linux Test Project From: Andrea Cervesato <andrea.cervesato@suse.com> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- include/lapi/pkt_cls.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/lapi/pkt_cls.h b/include/lapi/pkt_cls.h new file mode 100644 index 0000000000000000000000000000000000000000..b7a6278f07e6fcedcb7c412e833cb01170f24f74 --- /dev/null +++ b/include/lapi/pkt_cls.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +#ifndef LAPI_PKT_CLS_H__ +#define LAPI_PKT_CLS_H__ + +#include <linux/pkt_cls.h> + +#ifndef TC_ACT_PIPE +# define TC_ACT_PIPE 3 +#endif + +#ifndef TCA_MATCHALL_ACT +# define TCA_MATCHALL_ACT 2 +#endif + +#endif /* LAPI_PKT_CLS_H__ */ -- 2.51.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [LTP] lapi: Add pkt_cls.h fallback 2026-07-07 13:42 [LTP] [PATCH v3 1/4] " Andrea Cervesato @ 2026-07-07 14:28 ` linuxtestproject.agent 2026-07-07 14:53 ` Cyril Hrubis 0 siblings, 1 reply; 9+ messages in thread From: linuxtestproject.agent @ 2026-07-07 14:28 UTC (permalink / raw) To: Andrea Cervesato; +Cc: ltp Hi Andrea, On Tue, 7 Jul 2026 15:42:27 +0200, Andrea Cervesato wrote: > lapi: Add pkt_cls.h fallback --- [PATCH 3/4] --- > +#ifndef TCA_PEDIT_KEY_EX > +# define TCA_PEDIT_KEY_EX 3 > +#endif The value is wrong. Counting from TCA_PEDIT_UNSPEC = 0 in the kernel anonymous enum: TCA_PEDIT_UNSPEC = 0 TCA_PEDIT_TM = 1 TCA_PEDIT_PARMS = 2 TCA_PEDIT_PAD = 3 <-- 3 is PAD, not KEY_EX TCA_PEDIT_PARMS_EX = 4 TCA_PEDIT_KEYS_EX = 5 TCA_PEDIT_KEY_EX = 6 <-- should be 6 With value 3 the kernel would receive a TCA_PEDIT_PAD attribute where TCA_PEDIT_KEY_EX is expected and reject the filter with "Unknown attribute, expected extended key". This also breaks the test in patch 4/4 which uses TCA_PEDIT_KEY_EX as a netlink attribute type. > +#ifndef TCA_PEDIT_PARMS_EX > +# define TCA_PEDIT_PARMS_EX 4 > +#endif > + > +#ifndef TCA_PEDIT_KEYS_EX > +# define TCA_PEDIT_KEYS_EX 5 > +#endif > + > +#ifndef TCA_PEDIT_KEY_EX > +# define TCA_PEDIT_KEY_EX 3 > +#endif > + > +#ifndef TCA_PEDIT_KEY_EX_HTYPE > +# define TCA_PEDIT_KEY_EX_HTYPE 1 > +#endif > + > +#ifndef TCA_PEDIT_KEY_EX_CMD > +# define TCA_PEDIT_KEY_EX_CMD 2 > +#endif All five of these are anonymous enum values in the kernel header, not preprocessor macros. A #ifndef guard tests the preprocessor symbol table, which does not include enum constants. So every one of these #define lines executes unconditionally even on systems that already have the full kernel header -- the enum values are silently shadowed by the macros. For the four correctly-valued ones this has no observable impact today, but the guard gives a false sense of safety. For TCA_PEDIT_KEY_EX the wrong value makes the situation permanent on every system. The correct approach for enum-valued constants is to use AC_CHECK_DECLS in configure.ac, the same way this patch already uses AC_CHECK_TYPES for the two enum types: AC_CHECK_DECLS([TCA_PEDIT_PARMS_EX, TCA_PEDIT_KEYS_EX, TCA_PEDIT_KEY_EX, TCA_PEDIT_KEY_EX_HTYPE, TCA_PEDIT_KEY_EX_CMD],,,[ #include <linux/tc_act/tc_pedit.h>]) That generates HAVE_DECL_* macros which can be used as guards around the fallback defines. --- [PATCH 4/4] --- > +cve: Add act_pedit page-cache corruption test The fix commit 899ee91156e5 does not exist in torvalds/linux, and the field `tcfp_off_max_hint` mentioned in the commit body is absent from the kernel source. The fix has not been merged to mainline and is therefore not in any released kernel, including 7.2. Per the staging rule, a test for an unreleased fix must: - carry a [STAGING] subject prefix, and - be listed in runtest/staging, not runtest/cve. > + .tags = (const struct tst_tag[]) { > + {"linux-git", "899ee91156e5"}, The SHA 899ee91156e5 cannot be resolved in torvalds/linux. Update this to the correct SHA once the fix is merged. Verdict - Needs revision --- Note: The agent can sometimes produce false positives although often its findings are genuine. If you find issues with the review, please comment this email or ignore the suggestions. Regards, LTP AI Reviewer -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [LTP] lapi: Add pkt_cls.h fallback 2026-07-07 14:28 ` [LTP] " linuxtestproject.agent @ 2026-07-07 14:53 ` Cyril Hrubis 0 siblings, 0 replies; 9+ messages in thread From: Cyril Hrubis @ 2026-07-07 14:53 UTC (permalink / raw) To: linuxtestproject.agent; +Cc: ltp Hi! > TCA_PEDIT_UNSPEC = 0 > TCA_PEDIT_TM = 1 > TCA_PEDIT_PARMS = 2 > TCA_PEDIT_PAD = 3 <-- 3 is PAD, not KEY_EX > TCA_PEDIT_PARMS_EX = 4 > TCA_PEDIT_KEYS_EX = 5 > TCA_PEDIT_KEY_EX = 6 <-- should be 6 > > With value 3 the kernel would receive a TCA_PEDIT_PAD attribute where > TCA_PEDIT_KEY_EX is expected and reject the filter with "Unknown > attribute, expected extended key". > > This also breaks the test in patch 4/4 which uses TCA_PEDIT_KEY_EX > as a netlink attribute type. > > > +#ifndef TCA_PEDIT_PARMS_EX > > +# define TCA_PEDIT_PARMS_EX 4 > > +#endif > > + > > +#ifndef TCA_PEDIT_KEYS_EX > > +# define TCA_PEDIT_KEYS_EX 5 > > +#endif > > + > > +#ifndef TCA_PEDIT_KEY_EX > > +# define TCA_PEDIT_KEY_EX 3 > > +#endif > > + > > +#ifndef TCA_PEDIT_KEY_EX_HTYPE > > +# define TCA_PEDIT_KEY_EX_HTYPE 1 > > +#endif > > + > > +#ifndef TCA_PEDIT_KEY_EX_CMD > > +# define TCA_PEDIT_KEY_EX_CMD 2 > > +#endif > > All five of these are anonymous enum values in the kernel header, not > preprocessor macros. A #ifndef guard tests the preprocessor symbol > table, which does not include enum constants. So every one of these > #define lines executes unconditionally even on systems that already > have the full kernel header -- the enum values are silently shadowed > by the macros. > > For the four correctly-valued ones this has no observable impact > today, but the guard gives a false sense of safety. For > TCA_PEDIT_KEY_EX the wrong value makes the situation permanent on > every system. > > The correct approach for enum-valued constants is to use > AC_CHECK_DECLS in configure.ac, the same way this patch already uses > AC_CHECK_TYPES for the two enum types: > > AC_CHECK_DECLS([TCA_PEDIT_PARMS_EX, TCA_PEDIT_KEYS_EX, > TCA_PEDIT_KEY_EX, TCA_PEDIT_KEY_EX_HTYPE, > TCA_PEDIT_KEY_EX_CMD],,,[ > #include <linux/tc_act/tc_pedit.h>]) Maybe we can use the TCA_PEDIT_MAX: #if !defined(TCA_PEDI_MAX) || TCA_PEDIT_MAX < 4 # define TCA_PEDIT_PARMS_EX 4 #endif #if !defined(TCA_PEDI_MAX) || TCA_PEDIT_MAX < 5 # define TCA_PEDIT_KEYS_EX 5 #endif And we can use the same pattern with the rest of the enums. -- Cyril Hrubis chrubis@suse.cz -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-14 10:54 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-14 8:38 [LTP] [PATCH v5 0/4] Reproducer for cve-2026-46331 Andrea Cervesato 2026-07-14 8:38 ` [LTP] [PATCH v5 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato 2026-07-14 10:53 ` [LTP] " linuxtestproject.agent 2026-07-14 8:38 ` [LTP] [PATCH v5 2/4] lapi: Add pkt_sched.h fallback Andrea Cervesato 2026-07-14 8:39 ` [LTP] [PATCH v5 3/4] lapi: Add tc_pedit.h fallback Andrea Cervesato 2026-07-14 8:39 ` [LTP] [PATCH v5 4/4] cve: Add act_pedit page-cache corruption test Andrea Cervesato -- strict thread matches above, loose matches on Subject: below -- 2026-07-13 12:37 [LTP] [PATCH v4 1/4] lapi: Add pkt_cls.h fallback Andrea Cervesato 2026-07-13 14:13 ` [LTP] " linuxtestproject.agent 2026-07-07 13:42 [LTP] [PATCH v3 1/4] " Andrea Cervesato 2026-07-07 14:28 ` [LTP] " linuxtestproject.agent 2026-07-07 14:53 ` Cyril Hrubis
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.