Skip to content

Commit d7e8259

Browse files
committed
selftests: tls: test TCP stealing data from under the TLS socket
Check a race where data disappears from the TCP socket after TLS signaled that its ready to receive. ok 6 global.data_steal # RUN tls_basic.base_base ... # OK tls_basic.base_base Reviewed-by: Eric Dumazet <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6db015f commit d7e8259

File tree

1 file changed

+63
-0
lines changed
  • tools/testing/selftests/net

1 file changed

+63
-0
lines changed

tools/testing/selftests/net/tls.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,69 @@ TEST(prequeue) {
27082708
close(cfd);
27092709
}
27102710

2711+
TEST(data_steal) {
2712+
struct tls_crypto_info_keys tls;
2713+
char buf[20000], buf2[20000];
2714+
struct sockaddr_in addr;
2715+
int sfd, cfd, ret, fd;
2716+
int pid, status;
2717+
socklen_t len;
2718+
2719+
len = sizeof(addr);
2720+
memrnd(buf, sizeof(buf));
2721+
2722+
tls_crypto_info_init(TLS_1_2_VERSION, TLS_CIPHER_AES_GCM_256, &tls, 0);
2723+
2724+
addr.sin_family = AF_INET;
2725+
addr.sin_addr.s_addr = htonl(INADDR_ANY);
2726+
addr.sin_port = 0;
2727+
2728+
fd = socket(AF_INET, SOCK_STREAM, 0);
2729+
sfd = socket(AF_INET, SOCK_STREAM, 0);
2730+
2731+
ASSERT_EQ(bind(sfd, &addr, sizeof(addr)), 0);
2732+
ASSERT_EQ(listen(sfd, 10), 0);
2733+
ASSERT_EQ(getsockname(sfd, &addr, &len), 0);
2734+
ASSERT_EQ(connect(fd, &addr, sizeof(addr)), 0);
2735+
ASSERT_GE(cfd = accept(sfd, &addr, &len), 0);
2736+
close(sfd);
2737+
2738+
ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
2739+
if (ret) {
2740+
ASSERT_EQ(errno, ENOENT);
2741+
SKIP(return, "no TLS support");
2742+
}
2743+
ASSERT_EQ(setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls")), 0);
2744+
2745+
/* Spawn a child and get it into the read wait path of the underlying
2746+
* TCP socket.
2747+
*/
2748+
pid = fork();
2749+
ASSERT_GE(pid, 0);
2750+
if (!pid) {
2751+
EXPECT_EQ(recv(cfd, buf, sizeof(buf), MSG_WAITALL),
2752+
sizeof(buf));
2753+
exit(!__test_passed(_metadata));
2754+
}
2755+
2756+
usleep(2000);
2757+
ASSERT_EQ(setsockopt(fd, SOL_TLS, TLS_TX, &tls, tls.len), 0);
2758+
ASSERT_EQ(setsockopt(cfd, SOL_TLS, TLS_RX, &tls, tls.len), 0);
2759+
2760+
EXPECT_EQ(send(fd, buf, sizeof(buf), 0), sizeof(buf));
2761+
usleep(2000);
2762+
EXPECT_EQ(recv(cfd, buf2, sizeof(buf2), MSG_DONTWAIT), -1);
2763+
/* Don't check errno, the error will be different depending
2764+
* on what random bytes TLS interpreted as the record length.
2765+
*/
2766+
2767+
close(fd);
2768+
close(cfd);
2769+
2770+
EXPECT_EQ(wait(&status), pid);
2771+
EXPECT_EQ(status, 0);
2772+
}
2773+
27112774
static void __attribute__((constructor)) fips_check(void) {
27122775
int res;
27132776
FILE *f;

0 commit comments

Comments
 (0)