]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.0/net-tls-don-t-leak-partially-sent-record-in-device-mode.patch
5.0-stable patches
[thirdparty/kernel/stable-queue.git] / queue-5.0 / net-tls-don-t-leak-partially-sent-record-in-device-mode.patch
1 From foo@baz Sat Apr 20 16:43:09 CEST 2019
2 From: Jakub Kicinski <jakub.kicinski@netronome.com>
3 Date: Wed, 10 Apr 2019 11:04:31 -0700
4 Subject: net/tls: don't leak partially sent record in device mode
5
6 From: Jakub Kicinski <jakub.kicinski@netronome.com>
7
8 [ Upstream commit 35b71a34ada62c9573847a324bf06a133fe11b11 ]
9
10 David reports that tls triggers warnings related to
11 sk->sk_forward_alloc not being zero at destruction time:
12
13 WARNING: CPU: 5 PID: 6831 at net/core/stream.c:206 sk_stream_kill_queues+0x103/0x110
14 WARNING: CPU: 5 PID: 6831 at net/ipv4/af_inet.c:160 inet_sock_destruct+0x15b/0x170
15
16 When sender fills up the write buffer and dies from
17 SIGPIPE. This is due to the device implementation
18 not cleaning up the partially_sent_record.
19
20 This is because commit a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance")
21 moved the partial record cleanup to the SW-only path.
22
23 Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance")
24 Reported-by: David Beckett <david.beckett@netronome.com>
25 Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
26 Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
27 Reviewed-by: Simon Horman <simon.horman@netronome.com>
28 Signed-off-by: David S. Miller <davem@davemloft.net>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30 ---
31 include/net/tls.h | 2 ++
32 net/tls/tls_device.c | 7 +++++++
33 net/tls/tls_main.c | 22 ++++++++++++++++++++++
34 net/tls/tls_sw.c | 15 +--------------
35 4 files changed, 32 insertions(+), 14 deletions(-)
36
37 --- a/include/net/tls.h
38 +++ b/include/net/tls.h
39 @@ -289,6 +289,7 @@ int tls_device_sendmsg(struct sock *sk,
40 int tls_device_sendpage(struct sock *sk, struct page *page,
41 int offset, size_t size, int flags);
42 void tls_device_sk_destruct(struct sock *sk);
43 +void tls_device_free_resources_tx(struct sock *sk);
44 void tls_device_init(void);
45 void tls_device_cleanup(void);
46 int tls_tx_records(struct sock *sk, int flags);
47 @@ -312,6 +313,7 @@ int tls_push_sg(struct sock *sk, struct
48 int flags);
49 int tls_push_partial_record(struct sock *sk, struct tls_context *ctx,
50 int flags);
51 +bool tls_free_partial_record(struct sock *sk, struct tls_context *ctx);
52
53 int tls_push_pending_closed_record(struct sock *sk, struct tls_context *ctx,
54 int flags, long *timeo);
55 --- a/net/tls/tls_device.c
56 +++ b/net/tls/tls_device.c
57 @@ -219,6 +219,13 @@ void tls_device_sk_destruct(struct sock
58 }
59 EXPORT_SYMBOL(tls_device_sk_destruct);
60
61 +void tls_device_free_resources_tx(struct sock *sk)
62 +{
63 + struct tls_context *tls_ctx = tls_get_ctx(sk);
64 +
65 + tls_free_partial_record(sk, tls_ctx);
66 +}
67 +
68 static void tls_append_frag(struct tls_record_info *record,
69 struct page_frag *pfrag,
70 int size)
71 --- a/net/tls/tls_main.c
72 +++ b/net/tls/tls_main.c
73 @@ -220,6 +220,26 @@ int tls_push_pending_closed_record(struc
74 return tls_ctx->push_pending_record(sk, flags);
75 }
76
77 +bool tls_free_partial_record(struct sock *sk, struct tls_context *ctx)
78 +{
79 + struct scatterlist *sg;
80 +
81 + sg = ctx->partially_sent_record;
82 + if (!sg)
83 + return false;
84 +
85 + while (1) {
86 + put_page(sg_page(sg));
87 + sk_mem_uncharge(sk, sg->length);
88 +
89 + if (sg_is_last(sg))
90 + break;
91 + sg++;
92 + }
93 + ctx->partially_sent_record = NULL;
94 + return true;
95 +}
96 +
97 static void tls_write_space(struct sock *sk)
98 {
99 struct tls_context *ctx = tls_get_ctx(sk);
100 @@ -278,6 +298,8 @@ static void tls_sk_proto_close(struct so
101 kfree(ctx->tx.rec_seq);
102 kfree(ctx->tx.iv);
103 tls_sw_free_resources_tx(sk);
104 + } else if (ctx->tx_conf == TLS_HW) {
105 + tls_device_free_resources_tx(sk);
106 }
107
108 if (ctx->rx_conf == TLS_SW) {
109 --- a/net/tls/tls_sw.c
110 +++ b/net/tls/tls_sw.c
111 @@ -1804,20 +1804,7 @@ void tls_sw_free_resources_tx(struct soc
112 /* Free up un-sent records in tx_list. First, free
113 * the partially sent record if any at head of tx_list.
114 */
115 - if (tls_ctx->partially_sent_record) {
116 - struct scatterlist *sg = tls_ctx->partially_sent_record;
117 -
118 - while (1) {
119 - put_page(sg_page(sg));
120 - sk_mem_uncharge(sk, sg->length);
121 -
122 - if (sg_is_last(sg))
123 - break;
124 - sg++;
125 - }
126 -
127 - tls_ctx->partially_sent_record = NULL;
128 -
129 + if (tls_free_partial_record(sk, tls_ctx)) {
130 rec = list_first_entry(&ctx->tx_list,
131 struct tls_rec, list);
132 list_del(&rec->list);