]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/net-tls-fix-copy-to-fragments-in-reencrypt.patch
dae3de487f0d0dd00119533b732897ddb96571ad
[thirdparty/kernel/stable-queue.git] / queue-4.19 / net-tls-fix-copy-to-fragments-in-reencrypt.patch
1 From foo@baz Sat 04 May 2019 09:23:44 AM CEST
2 From: Jakub Kicinski <jakub.kicinski@netronome.com>
3 Date: Thu, 25 Apr 2019 17:35:10 -0700
4 Subject: net/tls: fix copy to fragments in reencrypt
5
6 From: Jakub Kicinski <jakub.kicinski@netronome.com>
7
8 [ Upstream commit eb3d38d5adb520435d4e4af32529ccb13ccc9935 ]
9
10 Fragments may contain data from other records so we have to account
11 for that when we calculate the destination and max length of copy we
12 can perform. Note that 'offset' is the offset within the message,
13 so it can't be passed as offset within the frag..
14
15 Here skb_store_bits() would have realised the call is wrong and
16 simply not copy data.
17
18 Fixes: 4799ac81e52a ("tls: Add rx inline crypto offload")
19 Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
20 Reviewed-by: John Hurley <john.hurley@netronome.com>
21 Signed-off-by: David S. Miller <davem@davemloft.net>
22 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23 ---
24 net/tls/tls_device.c | 29 ++++++++++++++++++++++-------
25 1 file changed, 22 insertions(+), 7 deletions(-)
26
27 --- a/net/tls/tls_device.c
28 +++ b/net/tls/tls_device.c
29 @@ -569,7 +569,7 @@ void handle_device_resync(struct sock *s
30 static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
31 {
32 struct strp_msg *rxm = strp_msg(skb);
33 - int err = 0, offset = rxm->offset, copy, nsg;
34 + int err = 0, offset = rxm->offset, copy, nsg, data_len, pos;
35 struct sk_buff *skb_iter, *unused;
36 struct scatterlist sg[1];
37 char *orig_buf, *buf;
38 @@ -600,9 +600,10 @@ static int tls_device_reencrypt(struct s
39 else
40 err = 0;
41
42 + data_len = rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE;
43 +
44 if (skb_pagelen(skb) > offset) {
45 - copy = min_t(int, skb_pagelen(skb) - offset,
46 - rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE);
47 + copy = min_t(int, skb_pagelen(skb) - offset, data_len);
48
49 if (skb->decrypted)
50 skb_store_bits(skb, offset, buf, copy);
51 @@ -611,16 +612,30 @@ static int tls_device_reencrypt(struct s
52 buf += copy;
53 }
54
55 + pos = skb_pagelen(skb);
56 skb_walk_frags(skb, skb_iter) {
57 - copy = min_t(int, skb_iter->len,
58 - rxm->full_len - offset + rxm->offset -
59 - TLS_CIPHER_AES_GCM_128_TAG_SIZE);
60 + int frag_pos;
61 +
62 + /* Practically all frags must belong to msg if reencrypt
63 + * is needed with current strparser and coalescing logic,
64 + * but strparser may "get optimized", so let's be safe.
65 + */
66 + if (pos + skb_iter->len <= offset)
67 + goto done_with_frag;
68 + if (pos >= data_len + rxm->offset)
69 + break;
70 +
71 + frag_pos = offset - pos;
72 + copy = min_t(int, skb_iter->len - frag_pos,
73 + data_len + rxm->offset - offset);
74
75 if (skb_iter->decrypted)
76 - skb_store_bits(skb_iter, offset, buf, copy);
77 + skb_store_bits(skb_iter, frag_pos, buf, copy);
78
79 offset += copy;
80 buf += copy;
81 +done_with_frag:
82 + pos += skb_iter->len;
83 }
84
85 free_buf: