]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests: tls: add a test for splicing onto a full plaintext record
authorchanyoung <ppoo1220@gmail.com>
Tue, 4 Aug 2026 05:28:36 +0000 (14:28 +0900)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Aug 2026 16:01:54 +0000 (09:01 -0700)
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>
tools/testing/selftests/net/tls.c

index cbdd3ea28b998f7663572208eab6964dcc746b1b..3d6f553eaf973d86c1b05200ae8c9aa5bc7d677b 100644 (file)
@@ -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;