Commit 3834e079d67f for kernel
commit 3834e079d67feda5fd57d1ea8d4185d316997335
Author: chanyoung <ppoo1220@gmail.com>
Date: Tue Aug 4 14:28:36 2026 +0900
selftests: tls: add a test for splicing onto a full plaintext record
Splicing onto a plaintext sk_msg ring that is already full used to wrap the
ring and make the kernel oops in the scatterwalk once the record was
pushed.
Only the copy path leaves the ring full without pushing it, so splice until
the ring is one fragment short, add the last fragment with a one-byte
MSG_MORE send, and splice once more before pushing the record.
CONFIG_MAX_SKB_FRAGS is 17..45, so that last fragment follows between 16
and 44 splices; sweep that range to trigger the bug on any build.
Signed-off-by: chanyoung <ppoo1220@gmail.com>
Link: https://patch.msgid.link/20260804052837.49015-3-ppoo1220@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
index cbdd3ea28b99..3d6f553eaf97 100644
--- a/tools/testing/selftests/net/tls.c
+++ b/tools/testing/selftests/net/tls.c
@@ -835,6 +835,43 @@ TEST_F(tls, send_and_splice)
EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
}
+TEST_F(tls, splice_onto_full_record)
+{
+ char mem_send[4608];
+ char mem_recv[4608];
+ int frag_len = 100;
+ int nfrags, i, off;
+ int p[2];
+
+ memrnd(mem_send, sizeof(mem_send));
+ ASSERT_GE(pipe(p), 0);
+
+ for (nfrags = 16; nfrags <= 44; nfrags++) {
+ for (i = 0, off = 0; i < nfrags; i++, off += frag_len) {
+ EXPECT_EQ(write(p[1], mem_send + off, frag_len), frag_len);
+ EXPECT_EQ(splice(p[0], NULL, self->fd, NULL, frag_len,
+ SPLICE_F_MORE), frag_len);
+ }
+
+ EXPECT_EQ(send(self->fd, mem_send + off, 1, MSG_MORE), 1);
+ off++;
+
+ EXPECT_EQ(write(p[1], mem_send + off, frag_len), frag_len);
+ EXPECT_EQ(splice(p[0], NULL, self->fd, NULL, frag_len,
+ SPLICE_F_MORE), frag_len);
+ off += frag_len;
+
+ EXPECT_EQ(send(self->fd, mem_send + off, 1, 0), 1);
+ off++;
+
+ EXPECT_EQ(recv(self->cfd, mem_recv, off, MSG_WAITALL), off);
+ EXPECT_EQ(memcmp(mem_send, mem_recv, off), 0);
+ }
+
+ close(p[0]);
+ close(p[1]);
+}
+
TEST_F(tls, splice_to_pipe)
{
int send_len = TLS_PAYLOAD_MAX_LEN;