Skip to content

Commit fbef947

Browse files
committed
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 <[email protected]>
2 parents b2a20fd + eb3d38d commit fbef947

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

net/tls/tls_device.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ void handle_device_resync(struct sock *sk, u32 seq, u64 rcd_sn)
597597
static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
598598
{
599599
struct strp_msg *rxm = strp_msg(skb);
600-
int err = 0, offset = rxm->offset, copy, nsg;
600+
int err = 0, offset = rxm->offset, copy, nsg, data_len, pos;
601601
struct sk_buff *skb_iter, *unused;
602602
struct scatterlist sg[1];
603603
char *orig_buf, *buf;
@@ -628,25 +628,42 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb)
628628
else
629629
err = 0;
630630

631-
copy = min_t(int, skb_pagelen(skb) - offset,
632-
rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE);
631+
data_len = rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE;
633632

634-
if (skb->decrypted)
635-
skb_store_bits(skb, offset, buf, copy);
633+
if (skb_pagelen(skb) > offset) {
634+
copy = min_t(int, skb_pagelen(skb) - offset, data_len);
636635

637-
offset += copy;
638-
buf += copy;
636+
if (skb->decrypted)
637+
skb_store_bits(skb, offset, buf, copy);
639638

639+
offset += copy;
640+
buf += copy;
641+
}
642+
643+
pos = skb_pagelen(skb);
640644
skb_walk_frags(skb, skb_iter) {
641-
copy = min_t(int, skb_iter->len,
642-
rxm->full_len - offset + rxm->offset -
643-
TLS_CIPHER_AES_GCM_128_TAG_SIZE);
645+
int frag_pos;
646+
647+
/* Practically all frags must belong to msg if reencrypt
648+
* is needed with current strparser and coalescing logic,
649+
* but strparser may "get optimized", so let's be safe.
650+
*/
651+
if (pos + skb_iter->len <= offset)
652+
goto done_with_frag;
653+
if (pos >= data_len + rxm->offset)
654+
break;
655+
656+
frag_pos = offset - pos;
657+
copy = min_t(int, skb_iter->len - frag_pos,
658+
data_len + rxm->offset - offset);
644659

645660
if (skb_iter->decrypted)
646-
skb_store_bits(skb_iter, offset, buf, copy);
661+
skb_store_bits(skb_iter, frag_pos, buf, copy);
647662

648663
offset += copy;
649664
buf += copy;
665+
done_with_frag:
666+
pos += skb_iter->len;
650667
}
651668

652669
free_buf:

0 commit comments

Comments
 (0)