From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
andrew+netdev@lunn.ch, horms@kernel.org, sd@queasysnail.net,
john.fastabend@gmail.com, shuah@kernel.org, cel@kernel.org,
linux-kselftest@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net v2 5/5] selftests: tls: Cover the cap on consecutive empty records
Date: Wed, 11 Nov 2026 10:55:22 -0800 [thread overview]
Message-ID: <20261111185522.2859004-6-kuba@kernel.org> (raw)
In-Reply-To: <20261111185522.2859004-1-kuba@kernel.org>
Check through both recv() and splice() that a run of 128 empty data
records is consumed and the data record behind it is delivered, and
that a run of 129 breaks the connection with EBADMSG before the data
record can be read. Two runs of 128 with a read returning EAGAIN in
between must not break the connection, the cap applies to a burst the
reader cannot keep up with, not to the connection as a whole.
kTLS cannot send an empty record. A TLS 1.3 record of type 0 whose
only byte is the data content type decrypts to one, since the receiver
strips the 0 as padding.
Reviewed-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2: no change
v1: https://lore.kernel.org/20261109175836.1246840-6-kuba@kernel.org
---
tools/testing/selftests/net/tls.c | 124 ++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
index c505508afde5..bd2797f9f619 100644
--- a/tools/testing/selftests/net/tls.c
+++ b/tools/testing/selftests/net/tls.c
@@ -2894,6 +2894,130 @@ TEST_F(zero_len_splice, test)
close(p[1]);
}
+FIXTURE(zero_len_run)
+{
+ int fd, cfd;
+ bool notls;
+};
+
+/* Before each of two reads, send n[i] empty records followed by a data
+ * record if data[i] is set. ret[i] is the result of the read.
+ */
+FIXTURE_VARIANT(zero_len_run)
+{
+ unsigned int n[2];
+ bool data[2];
+ int ret[2];
+};
+
+FIXTURE_VARIANT_ADD(zero_len_run, 128)
+{
+ .n = { 128, 0, },
+ .data = { true, false, },
+ .ret = { 4, -EAGAIN, },
+};
+
+/* More than 128 consecutive empty records break the connection */
+FIXTURE_VARIANT_ADD(zero_len_run, 129)
+{
+ .n = { 129, 0, },
+ .data = { true, false, },
+ .ret = { -EBADMSG, -EAGAIN, },
+};
+
+/* The count starts over on every read */
+FIXTURE_VARIANT_ADD(zero_len_run, 128_128)
+{
+ .n = { 128, 128, },
+ .data = { false, true, },
+ .ret = { -EAGAIN, 4, },
+};
+
+FIXTURE_SETUP(zero_len_run)
+{
+ struct tls_crypto_info_keys tls13;
+ int ret;
+
+ tls_crypto_info_init(TLS_1_3_VERSION, TLS_CIPHER_AES_GCM_128,
+ &tls13, 0);
+
+ ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
+ if (self->notls)
+ return;
+
+ ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls13, tls13.len);
+ ASSERT_EQ(ret, 0);
+ ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls13, tls13.len);
+ ASSERT_EQ(ret, 0);
+}
+
+FIXTURE_TEARDOWN(zero_len_run)
+{
+ close(self->fd);
+ close(self->cfd);
+}
+
+static void zero_len_run_send(struct __test_metadata *_metadata, int fd,
+ const FIXTURE_VARIANT(zero_len_run) *variant,
+ int i)
+{
+ /* kTLS cannot send an empty record. Send the data content type as
+ * the only byte of a record of type 0 instead, the receiver strips
+ * the 0 as padding and sees an empty data record.
+ */
+ char data_type = 0x17;
+ unsigned int j;
+
+ for (j = 0; j < variant->n[i]; j++)
+ ASSERT_EQ(tls_send_cmsg(fd, 0, &data_type, 1, 0), 1);
+ if (variant->data[i])
+ ASSERT_EQ(send(fd, "data", 4, 0), 4);
+}
+
+static void zero_len_run_expect(struct __test_metadata *_metadata,
+ ssize_t ret, int expected)
+{
+ EXPECT_EQ(ret, expected >= 0 ? expected : -1);
+ if (expected < 0)
+ EXPECT_EQ(errno, -expected);
+}
+
+TEST_F(zero_len_run, recv)
+{
+ char buf[16];
+ int i;
+
+ if (self->notls)
+ SKIP(return, "no TLS support");
+
+ for (i = 0; i < 2; i++) {
+ zero_len_run_send(_metadata, self->fd, variant, i);
+ zero_len_run_expect(_metadata,
+ recv(self->cfd, buf, sizeof(buf),
+ MSG_DONTWAIT),
+ variant->ret[i]);
+ }
+}
+
+TEST_F(zero_len_run, splice)
+{
+ int i, p[2];
+
+ if (self->notls)
+ SKIP(return, "no TLS support");
+
+ ASSERT_GE(pipe(p), 0);
+ for (i = 0; i < 2; i++) {
+ zero_len_run_send(_metadata, self->fd, variant, i);
+ zero_len_run_expect(_metadata,
+ splice(self->cfd, NULL, p[1], NULL, 16,
+ SPLICE_F_NONBLOCK),
+ variant->ret[i]);
+ }
+ close(p[0]);
+ close(p[1]);
+}
+
FIXTURE(tls_err)
{
int fd, cfd;
--
2.56.0
prev parent reply other threads:[~2026-11-11 18:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 18:55 [PATCH net v2 0/5] net: tls: break the connection after a burst of empty data records Jakub Kicinski
2026-11-11 18:55 ` [PATCH net v2 1/5] tls: Break " Jakub Kicinski
2026-11-11 18:55 ` [PATCH net v2 2/5] tls: Consume empty data records in tls_sw_splice_read() Jakub Kicinski
2026-11-11 18:55 ` [PATCH net v2 3/5] selftests: tls: Skip the zero_len tests when TLS is unavailable Jakub Kicinski
2026-11-11 18:55 ` [PATCH net v2 4/5] selftests: tls: Extend coverage for zero-length records Jakub Kicinski
2026-11-11 18:55 ` Jakub Kicinski [this message]
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=20261111185522.2859004-6-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=cel@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=john.fastabend@gmail.com \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sd@queasysnail.net \
--cc=shuah@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox