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

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
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -1712,15 +1712,14 @@ int tls_sw_recvmsg(struct sock *sk,
		copied = err;
	}

	len = len - copied;
	if (len) {
	if (len <= copied)
		goto recv_end;

	target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
	len = len - copied;
	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 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) {
+34 −0
Original line number Diff line number Diff line
@@ -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)
{