]>
Commit | Line | Data |
---|---|---|
ffc20820 GKH |
1 | From foo@baz Fri 31 May 2019 03:16:39 PM PDT |
2 | From: Jakub Kicinski <jakub.kicinski@netronome.com> | |
3 | Date: Fri, 24 May 2019 10:34:32 -0700 | |
4 | Subject: net/tls: fix no wakeup on partial reads | |
5 | ||
6 | From: Jakub Kicinski <jakub.kicinski@netronome.com> | |
7 | ||
8 | [ Upstream commit 04b25a5411f966c2e586909a8496553b71876fae ] | |
9 | ||
10 | When tls_sw_recvmsg() partially copies a record it pops that | |
11 | record from ctx->recv_pkt and places it on rx_list. | |
12 | ||
13 | Next iteration of tls_sw_recvmsg() reads from rx_list via | |
14 | process_rx_list() before it enters the decryption loop. | |
15 | If there is no more records to be read tls_wait_data() | |
16 | will put the process on the wait queue and got to sleep. | |
17 | This is incorrect, because some data was already copied | |
18 | in process_rx_list(). | |
19 | ||
20 | In case of RPC connections process may never get woken up, | |
21 | because peer also simply blocks in read(). | |
22 | ||
23 | I think this may also fix a similar issue when BPF is at | |
24 | play, because after __tcp_bpf_recvmsg() returns some data | |
25 | we subtract it from len and use continue to restart the | |
26 | loop, but len could have just reached 0, so again we'd | |
27 | sleep unnecessarily. That's added by: | |
28 | commit d3b18ad31f93 ("tls: add bpf support to sk_msg handling") | |
29 | ||
30 | Fixes: 692d7b5d1f91 ("tls: Fix recvmsg() to be able to peek across multiple records") | |
31 | Reported-by: David Beckett <david.beckett@netronome.com> | |
32 | Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> | |
33 | Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com> | |
34 | Tested-by: David Beckett <david.beckett@netronome.com> | |
35 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
36 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
37 | --- | |
38 | net/tls/tls_sw.c | 8 ++------ | |
39 | 1 file changed, 2 insertions(+), 6 deletions(-) | |
40 | ||
41 | --- a/net/tls/tls_sw.c | |
42 | +++ b/net/tls/tls_sw.c | |
43 | @@ -1692,7 +1692,7 @@ int tls_sw_recvmsg(struct sock *sk, | |
44 | len = len - copied; | |
45 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | |
46 | ||
47 | - do { | |
48 | + while (len && (decrypted + copied < target || ctx->recv_pkt)) { | |
49 | bool retain_skb = false; | |
50 | bool zc = false; | |
51 | int to_decrypt; | |
52 | @@ -1823,11 +1823,7 @@ pick_next_record: | |
53 | } else { | |
54 | break; | |
55 | } | |
56 | - | |
57 | - /* If we have a new message from strparser, continue now. */ | |
58 | - if (decrypted + copied >= target && !ctx->recv_pkt) | |
59 | - break; | |
60 | - } while (len); | |
61 | + } | |
62 | ||
63 | recv_end: | |
64 | if (num_async) { |