Skip to content

Commit

Permalink
selftests: tls: add tests for poll behavior
Browse files Browse the repository at this point in the history
Make sure we don't generate premature POLLIN events.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
kuba-moo authored and davem330 committed Jun 2, 2023
1 parent 121dca7 commit 23fcb62
Showing 1 changed file with 131 additions and 0 deletions.
131 changes: 131 additions & 0 deletions tools/testing/selftests/net/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/tcp.h>
#include <linux/socket.h>

#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/sendfile.h>
#include <sys/socket.h>
Expand Down Expand Up @@ -1637,6 +1638,136 @@ TEST_F(tls_err, timeo)
}
}

TEST_F(tls_err, poll_partial_rec)
{
struct pollfd pfd = { };
ssize_t rec_len;
char rec[256];
char buf[128];

if (self->notls)
SKIP(return, "no TLS support");

pfd.fd = self->cfd2;
pfd.events = POLLIN;
EXPECT_EQ(poll(&pfd, 1, 1), 0);

memrnd(buf, sizeof(buf));
EXPECT_EQ(send(self->fd, buf, sizeof(buf), 0), sizeof(buf));
rec_len = recv(self->cfd, rec, sizeof(rec), 0);
EXPECT_GT(rec_len, sizeof(buf));

/* Write 100B, not the full record ... */
EXPECT_EQ(send(self->fd2, rec, 100, 0), 100);
/* ... no full record should mean no POLLIN */
pfd.fd = self->cfd2;
pfd.events = POLLIN;
EXPECT_EQ(poll(&pfd, 1, 1), 0);
/* Now write the rest, and it should all pop out of the other end. */
EXPECT_EQ(send(self->fd2, rec + 100, rec_len - 100, 0), rec_len - 100);
pfd.fd = self->cfd2;
pfd.events = POLLIN;
EXPECT_EQ(poll(&pfd, 1, 1), 1);
EXPECT_EQ(recv(self->cfd2, rec, sizeof(rec), 0), sizeof(buf));
EXPECT_EQ(memcmp(buf, rec, sizeof(buf)), 0);
}

TEST_F(tls_err, epoll_partial_rec)
{
struct epoll_event ev, events[10];
ssize_t rec_len;
char rec[256];
char buf[128];
int epollfd;

if (self->notls)
SKIP(return, "no TLS support");

epollfd = epoll_create1(0);
ASSERT_GE(epollfd, 0);

memset(&ev, 0, sizeof(ev));
ev.events = EPOLLIN;
ev.data.fd = self->cfd2;
ASSERT_GE(epoll_ctl(epollfd, EPOLL_CTL_ADD, self->cfd2, &ev), 0);

EXPECT_EQ(epoll_wait(epollfd, events, 10, 0), 0);

memrnd(buf, sizeof(buf));
EXPECT_EQ(send(self->fd, buf, sizeof(buf), 0), sizeof(buf));
rec_len = recv(self->cfd, rec, sizeof(rec), 0);
EXPECT_GT(rec_len, sizeof(buf));

/* Write 100B, not the full record ... */
EXPECT_EQ(send(self->fd2, rec, 100, 0), 100);
/* ... no full record should mean no POLLIN */
EXPECT_EQ(epoll_wait(epollfd, events, 10, 0), 0);
/* Now write the rest, and it should all pop out of the other end. */
EXPECT_EQ(send(self->fd2, rec + 100, rec_len - 100, 0), rec_len - 100);
EXPECT_EQ(epoll_wait(epollfd, events, 10, 0), 1);
EXPECT_EQ(recv(self->cfd2, rec, sizeof(rec), 0), sizeof(buf));
EXPECT_EQ(memcmp(buf, rec, sizeof(buf)), 0);

close(epollfd);
}

TEST_F(tls_err, poll_partial_rec_async)
{
struct pollfd pfd = { };
ssize_t rec_len;
char rec[256];
char buf[128];
char token;
int p[2];
int ret;

if (self->notls)
SKIP(return, "no TLS support");

ASSERT_GE(pipe(p), 0);

memrnd(buf, sizeof(buf));
EXPECT_EQ(send(self->fd, buf, sizeof(buf), 0), sizeof(buf));
rec_len = recv(self->cfd, rec, sizeof(rec), 0);
EXPECT_GT(rec_len, sizeof(buf));

ret = fork();
ASSERT_GE(ret, 0);

if (ret) {
int status, pid2;

close(p[1]);
usleep(1000); /* Give child a head start */

EXPECT_EQ(send(self->fd2, rec, 100, 0), 100);

EXPECT_EQ(read(p[0], &token, 1), 1); /* Barrier #1 */

EXPECT_EQ(send(self->fd2, rec + 100, rec_len - 100, 0),
rec_len - 100);

pid2 = wait(&status);
EXPECT_EQ(pid2, ret);
EXPECT_EQ(status, 0);
} else {
close(p[0]);

/* Child should sleep in poll(), never get a wake */
pfd.fd = self->cfd2;
pfd.events = POLLIN;
EXPECT_EQ(poll(&pfd, 1, 5), 0);

EXPECT_EQ(write(p[1], &token, 1), 1); /* Barrier #1 */

pfd.fd = self->cfd2;
pfd.events = POLLIN;
EXPECT_EQ(poll(&pfd, 1, 5), 1);

exit(!_metadata->passed);
}
}

TEST(non_established) {
struct tls12_crypto_info_aes_gcm_256 tls12;
struct sockaddr_in addr;
Expand Down

0 comments on commit 23fcb62

Please sign in to comment.