Merge branch 'net-tls-two-fixes-for-rx_list-pre-handling'

Jakub Kicinski says:

====================
net/tls: two fixes for rx_list pre-handling

tls_sw_recvmsg() had been modified to cater better to async decrypt.
Partially read records now live on the rx_list. Data is copied from
this list before the old do {} while loop, and the not included
correctly in deciding whether to sleep or not and lowat threshold
handling. These modifications, unfortunately, added some bugs.

First patch fixes lowat - we need to calculate the threshold early
and make sure all copied data is compared to the threshold, not just
the freshly decrypted data.

Third patch fixes sleep - if data is picked up from rx_list and
no flags are set, we should not put the process to sleep, but
rather return the partial read.

Patches 2 and 4 add test cases for these bugs, both will cause
a sleep and test timeout before the fix.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-05-26 21:47:13 -07:00
commit b933dc367a
2 changed files with 41 additions and 12 deletions

View File

@ -1712,15 +1712,14 @@ int tls_sw_recvmsg(struct sock *sk,
copied = err;
}
len = len - copied;
if (len) {
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
} else {
if (len <= copied)
goto recv_end;
}
do {
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
len = len - copied;
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
while (len && (decrypted + copied < target || ctx->recv_pkt)) {
bool retain_skb = false;
bool zc = false;
int to_decrypt;
@ -1851,11 +1850,7 @@ pick_next_record:
} else {
break;
}
/* If we have a new message from strparser, continue now. */
if (decrypted >= target && !ctx->recv_pkt)
break;
} while (len);
}
recv_end:
if (num_async) {

View File

@ -442,6 +442,21 @@ TEST_F(tls, multiple_send_single_recv)
EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0);
}
TEST_F(tls, single_send_multiple_recv_non_align)
{
const unsigned int total_len = 15;
const unsigned int recv_len = 10;
char recv_mem[recv_len * 2];
char send_mem[total_len];
EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
memset(recv_mem, 0, total_len);
EXPECT_EQ(recv(self->cfd, recv_mem, recv_len, 0), recv_len);
EXPECT_EQ(recv(self->cfd, recv_mem + recv_len, recv_len, 0), 5);
EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
}
TEST_F(tls, recv_partial)
{
char const *test_str = "test_read_partial";
@ -575,6 +590,25 @@ TEST_F(tls, recv_peek_large_buf_mult_recs)
EXPECT_EQ(memcmp(test_str, buf, len), 0);
}
TEST_F(tls, recv_lowat)
{
char send_mem[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
char recv_mem[20];
int lowat = 8;
EXPECT_EQ(send(self->fd, send_mem, 10, 0), 10);
EXPECT_EQ(send(self->fd, send_mem, 5, 0), 5);
memset(recv_mem, 0, 20);
EXPECT_EQ(setsockopt(self->cfd, SOL_SOCKET, SO_RCVLOWAT,
&lowat, sizeof(lowat)), 0);
EXPECT_EQ(recv(self->cfd, recv_mem, 1, MSG_WAITALL), 1);
EXPECT_EQ(recv(self->cfd, recv_mem + 1, 6, MSG_WAITALL), 6);
EXPECT_EQ(recv(self->cfd, recv_mem + 7, 10, 0), 8);
EXPECT_EQ(memcmp(send_mem, recv_mem, 10), 0);
EXPECT_EQ(memcmp(send_mem, recv_mem + 10, 5), 0);
}
TEST_F(tls, pollin)
{