diff options
Diffstat (limited to 'net/tls/tls_device.c')
-rw-r--r-- | net/tls/tls_device.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 96357060addc..14dedb24fa7b 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c | |||
@@ -597,7 +597,7 @@ void handle_device_resync(struct sock *sk, u32 seq, u64 rcd_sn) | |||
597 | static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) | 597 | static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) |
598 | { | 598 | { |
599 | struct strp_msg *rxm = strp_msg(skb); | 599 | 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; |
601 | struct sk_buff *skb_iter, *unused; | 601 | struct sk_buff *skb_iter, *unused; |
602 | struct scatterlist sg[1]; | 602 | struct scatterlist sg[1]; |
603 | char *orig_buf, *buf; | 603 | char *orig_buf, *buf; |
@@ -628,9 +628,10 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) | |||
628 | else | 628 | else |
629 | err = 0; | 629 | err = 0; |
630 | 630 | ||
631 | data_len = rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE; | ||
632 | |||
631 | if (skb_pagelen(skb) > offset) { | 633 | if (skb_pagelen(skb) > offset) { |
632 | copy = min_t(int, skb_pagelen(skb) - offset, | 634 | copy = min_t(int, skb_pagelen(skb) - offset, data_len); |
633 | rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE); | ||
634 | 635 | ||
635 | if (skb->decrypted) | 636 | if (skb->decrypted) |
636 | skb_store_bits(skb, offset, buf, copy); | 637 | skb_store_bits(skb, offset, buf, copy); |
@@ -639,16 +640,30 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) | |||
639 | buf += copy; | 640 | buf += copy; |
640 | } | 641 | } |
641 | 642 | ||
643 | pos = skb_pagelen(skb); | ||
642 | skb_walk_frags(skb, skb_iter) { | 644 | skb_walk_frags(skb, skb_iter) { |
643 | copy = min_t(int, skb_iter->len, | 645 | int frag_pos; |
644 | rxm->full_len - offset + rxm->offset - | 646 | |
645 | TLS_CIPHER_AES_GCM_128_TAG_SIZE); | 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); | ||
646 | 659 | ||
647 | if (skb_iter->decrypted) | 660 | if (skb_iter->decrypted) |
648 | skb_store_bits(skb_iter, offset, buf, copy); | 661 | skb_store_bits(skb_iter, frag_pos, buf, copy); |
649 | 662 | ||
650 | offset += copy; | 663 | offset += copy; |
651 | buf += copy; | 664 | buf += copy; |
665 | done_with_frag: | ||
666 | pos += skb_iter->len; | ||
652 | } | 667 | } |
653 | 668 | ||
654 | free_buf: | 669 | free_buf: |