All of lore.kernel.org
 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: 19+ 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-04 18:00       ` [LTP] lapi: Add io_uring_clone_buffers and RDS_CMSG_ZCOPY_COOKIE fallbacks linuxtestproject.agent

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 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.