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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
fbef9478ff
|
@ -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,27 +628,44 @@ 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);
|
||||||
|
|
||||||
skb_walk_frags(skb, skb_iter) {
|
|
||||||
copy = min_t(int, skb_iter->len,
|
|
||||||
rxm->full_len - offset + rxm->offset -
|
|
||||||
TLS_CIPHER_AES_GCM_128_TAG_SIZE);
|
|
||||||
|
|
||||||
if (skb_iter->decrypted)
|
|
||||||
skb_store_bits(skb_iter, offset, buf, copy);
|
|
||||||
|
|
||||||
offset += copy;
|
offset += copy;
|
||||||
buf += copy;
|
buf += copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos = skb_pagelen(skb);
|
||||||
|
skb_walk_frags(skb, skb_iter) {
|
||||||
|
int frag_pos;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
skb_store_bits(skb_iter, frag_pos, buf, copy);
|
||||||
|
|
||||||
|
offset += copy;
|
||||||
|
buf += copy;
|
||||||
|
done_with_frag:
|
||||||
|
pos += skb_iter->len;
|
||||||
|
}
|
||||||
|
|
||||||
free_buf:
|
free_buf:
|
||||||
kfree(orig_buf);
|
kfree(orig_buf);
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in New Issue