Linux Test Project
 help / color / mirror / Atom feed
From: Petr Vorel <pvorel@suse.cz>
To: Sebastian Chlad <sebastianchlad@gmail.com>
Cc: Sebastian Chlad <sebastian.chlad@suse.com>, ltp@lists.linux.it
Subject: Re: [LTP] [PATCH v4] io_uring/pintheft: Add CVE-2026-43494 regression test
Date: Sun, 24 May 2026 20:16:39 +0200	[thread overview]
Message-ID: <20260524181639.GA26213@pevik> (raw)
In-Reply-To: <20260523165718.26187-1-sebastian.chlad@suse.com>

Hi Sebastian,

> Test for PinTheft (CVE-2026-43494), fixed by:
> e17492979319 ("net/rds: reset op_nents when zerocopy page pin fails")

Thanks you!

> The bug is in the RDS zerocopy send error path: when pinning user pages
> for zerocopy send fails partway through, the error cleanup drops a page
> reference that the RDS message cleanup will drop again. Combined with
> io_uring fixed buffer registrations, this double-drop drains the
> FOLL_PIN counter and causes a page-cache overwrite exploitable for local
> privilege escalation (PinTheft).

...
> +static void setup(void)
> +{
> +	struct io_uring_params params = {};
> +	struct iovec fixed_iov;
> +	int val;
> +
> +	page_size = SAFE_SYSCONF(_SC_PAGESIZE);
> +	io_uring_setup_supported_by_kernel();
> +
> +	/*
> +	 * The exploit primitive keeps one fixed-buffer registration alive and
> +	 * clones it to another ring.
> +	 */
> +	ring_fd1 = io_uring_setup(1, &params);
> +	if (ring_fd1 < 0)
> +		tst_brk(TBROK | TERRNO, "io_uring_setup() failed for first ring");
> +
> +	memset(&params, 0, sizeof(params));
> +
> +	ring_fd2 = io_uring_setup(1, &params);
> +	if (ring_fd2 < 0)
> +		tst_brk(TBROK | TERRNO, "io_uring_setup() failed for second ring");
> +
> +	rds_fd = socket(AF_RDS, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
> +	if (rds_fd < 0) {
> +		if (errno == EAFNOSUPPORT || errno == ESOCKTNOSUPPORT ||
> +		    errno == EPROTONOSUPPORT || errno == ENOPROTOOPT)
> +			tst_brk(TCONF | TERRNO, "RDS is not available");
> +
> +		tst_brk(TBROK | TERRNO, "socket(AF_RDS) failed");

Just a quick Sunday evening comment (not yet looking into the reproducer itself).
I wonder if we need this complicated check when we already have kconfig based
checks at the end. Could we just simply use SAFE_SOCKET() here? Or have you
encountered problems with older kernels?

And I haven't found any sysctl check (it's just a kernel module), which would be
then part of lib/tst_kconfig.c.

> +	}
> +
> +	/* PinTheft uses the RDS TCP transport, so base RDS is not enough. */
> +	val = RDS_TRANS_TCP;
> +	TEST(setsockopt(rds_fd, SOL_RDS, SO_RDS_TRANSPORT, &val, sizeof(val)));
> +
> +	if (TST_RET) {
> +		if (TST_ERR == ENOPROTOOPT || TST_ERR == EINVAL)
> +			tst_brk(TCONF | TERRNO, "RDS TCP transport is not available");
> +
> +		tst_brk(TBROK | TERRNO, "setsockopt(SO_RDS_TRANSPORT) failed");
And the same here just SAFE_SETSOCKOPT() ?
> +	}
...
> +	/*
> +	 * Register only the first page as an io_uring fixed buffer. This creates
> +	 * the long-term page pin whose reference accounting the RDS bug damages.
> +	 */
> +	if (io_uring_register(ring_fd1, IORING_REGISTER_BUFFERS, &fixed_iov, 1))
> +		tst_brk(TBROK | TERRNO, "IORING_REGISTER_BUFFERS failed");
> +
> +	buffer_registered = 1;
> +
> +	/*
> +	 * Clone the fixed buffer registration into the second ring, matching the
> +	 * public reproducer's lifetime pattern without performing the later
> +	 * page-cache overwrite stage.
> +	 */
> +	if (clone_buffers(ring_fd2, ring_fd1)) {
> +		if (errno == EINVAL || errno == EOPNOTSUPP)
> +			tst_brk(TCONF | TERRNO, "IORING_REGISTER_CLONE_BUFFERS is not supported");
Also here do we need it? IMHO CONFIG_IO_URING should be enough.
And if errno is really needed, it'd IMHO be better to be in handled in
clone_buffers(), not separately.

> +
> +		tst_brk(TBROK | TERRNO, "IORING_REGISTER_CLONE_BUFFERS failed");
> +	}
...
> +	/* Mirror the public PoC trigger: RDS zerocopy over TCP. */
> +	val = 1;
> +	if (setsockopt(rds_fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) {
> +		if (errno == ENOPROTOOPT || errno == EINVAL)
> +			tst_brk(TCONF | TERRNO, "SO_ZEROCOPY not supported on RDS sockets");
And here I'd also simplify with SAFE_SETSOCKOPT().
> +		tst_brk(TBROK | TERRNO, "setsockopt(SO_ZEROCOPY) failed");
> +	}
...
> +static struct tst_test test = {
> +	.test_all = run,
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.timeout = 60,
> +	.forks_child = 1,
> +	.taint_check = TST_TAINT_W | TST_TAINT_D,
> +	.needs_kconfigs = (const char *[]) {
> +		"CONFIG_RDS",
> +		"CONFIG_RDS_TCP",
CONFIG_RDS_TCP implies CONFIG_RDS.

Kind regards,
Petr

> +		"CONFIG_IO_URING",
> +		NULL
> +	},
> +	.save_restore = (const struct tst_path_val[]) {
> +		{"/proc/sys/kernel/io_uring_disabled", "0",
> +			TST_SR_SKIP_MISSING | TST_SR_TCONF_RO},
> +		{}
> +	},
> +	.tags = (const struct tst_tag[]) {
> +		{"linux-git", "e17492979319"},
> +		{"CVE", "2026-43494"},
> +		{}
> +	}
> +};

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  parent reply	other threads:[~2026-05-24 18:17 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-23 10:17 [LTP] [PATCH] io_uring/pintheft: Add CVE-2026-43494 regression test Sebastian Chlad
2026-05-23 11:19 ` [LTP] " linuxtestproject.agent
2026-05-25  9:36   ` Cyril Hrubis
2026-05-29 10:18     ` Andrea Cervesato via ltp
2026-05-29 11:56       ` Cyril Hrubis
2026-05-23 11:39 ` [LTP] [PATCH v2] " Sebastian Chlad
2026-05-23 13:30   ` [LTP] " linuxtestproject.agent
2026-05-23 15:10 ` [LTP] [PATCH v3] " Sebastian Chlad
2026-05-23 16:17   ` [LTP] " linuxtestproject.agent
2026-05-23 16:57 ` [LTP] [PATCH v4] " Sebastian Chlad
2026-05-23 18:07   ` [LTP] " linuxtestproject.agent
2026-05-24 18:16   ` Petr Vorel [this message]
2026-05-28 16:45     ` [LTP] [PATCH v4] " Martin Doucha
2026-05-28 21:31       ` Petr Vorel
2026-05-28 16:36   ` Martin Doucha
2026-06-04 16:38     ` [LTP] [PATCH v5 1/2] lapi: Add io_uring_clone_buffers and RDS_CMSG_ZCOPY_COOKIE fallbacks Sebastian Chlad
2026-06-04 16:38       ` [LTP] [PATCH v5 2/2] io_uring04: Add CVE-2026-43494 regression test Sebastian Chlad
2026-06-05 15:30         ` Martin Doucha
2026-06-10 14:52         ` Cyril Hrubis
2026-06-10 19:34           ` [LTP] [PATCH v6 1/2] lapi: Add io_uring_clone_buffers and RDS_CMSG_ZCOPY_COOKIE fallbacks Sebastian Chlad
2026-06-10 19:35             ` [LTP] [PATCH v6 2/2] io_uring04: Add CVE-2026-43494 regression test Sebastian Chlad
2026-06-10 19:44             ` [LTP] lapi: Add io_uring_clone_buffers and RDS_CMSG_ZCOPY_COOKIE fallbacks linuxtestproject.agent
2026-06-11 13:13             ` [LTP] [PATCH v6 1/2] " Cyril Hrubis
2026-06-04 18:00       ` [LTP] " linuxtestproject.agent
2026-06-10 14:30       ` [LTP] [PATCH v5 1/2] " Cyril Hrubis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260524181639.GA26213@pevik \
    --to=pvorel@suse.cz \
    --cc=ltp@lists.linux.it \
    --cc=sebastian.chlad@suse.com \
    --cc=sebastianchlad@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox