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

Merge branch 'tls-data-copies'

Jakub Kicinski says:

====================
net/tls: fix data copies in tls_device_reencrypt()

This series fixes the tls_device_reencrypt() which is broken
if record starts in the frags of the message skb.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b2a20fd0 eb3d38d5
...@@ -597,7 +597,7 @@ void handle_device_resync(struct sock *sk, u32 seq, u64 rcd_sn) ...@@ -597,7 +597,7 @@ void handle_device_resync(struct sock *sk, u32 seq, u64 rcd_sn)
static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
{ {
struct strp_msg *rxm = strp_msg(skb); struct strp_msg *rxm = strp_msg(skb);
int err = 0, offset = rxm->offset, copy, nsg; int err = 0, offset = rxm->offset, copy, nsg, data_len, pos;
struct sk_buff *skb_iter, *unused; struct sk_buff *skb_iter, *unused;
struct scatterlist sg[1]; struct scatterlist sg[1];
char *orig_buf, *buf; char *orig_buf, *buf;
...@@ -628,25 +628,42 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) ...@@ -628,25 +628,42 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
else else
err = 0; err = 0;
copy = min_t(int, skb_pagelen(skb) - offset, data_len = rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE;
rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE);
if (skb->decrypted) if (skb_pagelen(skb) > offset) {
skb_store_bits(skb, offset, buf, copy); copy = min_t(int, skb_pagelen(skb) - offset, data_len);
offset += copy; if (skb->decrypted)
buf += copy; skb_store_bits(skb, offset, buf, copy);
offset += copy;
buf += copy;
}
pos = skb_pagelen(skb);
skb_walk_frags(skb, skb_iter) { skb_walk_frags(skb, skb_iter) {
copy = min_t(int, skb_iter->len, int frag_pos;
rxm->full_len - offset + rxm->offset -
TLS_CIPHER_AES_GCM_128_TAG_SIZE); /* Practically all frags must belong to msg if reencrypt
* is needed with current strparser and coalescing logic,
* but strparser may "get optimized", so let's be safe.
*/
if (pos + skb_iter->len <= offset)
goto done_with_frag;
if (pos >= data_len + rxm->offset)
break;
frag_pos = offset - pos;
copy = min_t(int, skb_iter->len - frag_pos,
data_len + rxm->offset - offset);
if (skb_iter->decrypted) if (skb_iter->decrypted)
skb_store_bits(skb_iter, offset, buf, copy); skb_store_bits(skb_iter, frag_pos, buf, copy);
offset += copy; offset += copy;
buf += copy; buf += copy;
done_with_frag:
pos += skb_iter->len;
} }
free_buf: free_buf:
......
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