Commit b933dc36 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 66a04abf 043556d0
...@@ -1712,15 +1712,14 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1712,15 +1712,14 @@ int tls_sw_recvmsg(struct sock *sk,
copied = err; copied = err;
} }
len = len - copied; if (len <= copied)
if (len) { goto recv_end;
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
len = len - copied;
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
} else {
goto recv_end;
}
do { while (len && (decrypted + copied < target || ctx->recv_pkt)) {
bool retain_skb = false; bool retain_skb = false;
bool zc = false; bool zc = false;
int to_decrypt; int to_decrypt;
...@@ -1851,11 +1850,7 @@ int tls_sw_recvmsg(struct sock *sk, ...@@ -1851,11 +1850,7 @@ int tls_sw_recvmsg(struct sock *sk,
} else { } else {
break; break;
} }
}
/* If we have a new message from strparser, continue now. */
if (decrypted >= target && !ctx->recv_pkt)
break;
} while (len);
recv_end: recv_end:
if (num_async) { if (num_async) {
......
...@@ -442,6 +442,21 @@ TEST_F(tls, multiple_send_single_recv) ...@@ -442,6 +442,21 @@ TEST_F(tls, multiple_send_single_recv)
EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0); 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) TEST_F(tls, recv_partial)
{ {
char const *test_str = "test_read_partial"; char const *test_str = "test_read_partial";
...@@ -575,6 +590,25 @@ TEST_F(tls, recv_peek_large_buf_mult_recs) ...@@ -575,6 +590,25 @@ TEST_F(tls, recv_peek_large_buf_mult_recs)
EXPECT_EQ(memcmp(test_str, buf, len), 0); 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) TEST_F(tls, pollin)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment