tls: rx: strp: force mixed decrypted records into copy mode

If a record is partially decrypted we'll have to CoW it, anyway,
so go into copy mode and allocate a writable skb right away.

This will make subsequent fix simpler because we won't have to
teach tls_strp_msg_make_copy() how to copy skbs while preserving
decrypt status.

Tested-by: Shai Amiram <samiram@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jakub Kicinski
2023-05-16 18:50:38 -07:00
committed by David S. Miller
parent 210620ae44
commit 14c4be92eb
2 changed files with 21 additions and 5 deletions

View File

@@ -1587,6 +1587,16 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from)
to->l4_hash = from->l4_hash; to->l4_hash = from->l4_hash;
}; };
static inline int skb_cmp_decrypted(const struct sk_buff *skb1,
const struct sk_buff *skb2)
{
#ifdef CONFIG_TLS_DEVICE
return skb2->decrypted - skb1->decrypted;
#else
return 0;
#endif
}
static inline void skb_copy_decrypted(struct sk_buff *to, static inline void skb_copy_decrypted(struct sk_buff *to,
const struct sk_buff *from) const struct sk_buff *from)
{ {

View File

@@ -317,15 +317,19 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
return 0; return 0;
} }
static bool tls_strp_check_no_dup(struct tls_strparser *strp) static bool tls_strp_check_queue_ok(struct tls_strparser *strp)
{ {
unsigned int len = strp->stm.offset + strp->stm.full_len; unsigned int len = strp->stm.offset + strp->stm.full_len;
struct sk_buff *skb; struct sk_buff *first, *skb;
u32 seq; u32 seq;
skb = skb_shinfo(strp->anchor)->frag_list; first = skb_shinfo(strp->anchor)->frag_list;
seq = TCP_SKB_CB(skb)->seq; skb = first;
seq = TCP_SKB_CB(first)->seq;
/* Make sure there's no duplicate data in the queue,
* and the decrypted status matches.
*/
while (skb->len < len) { while (skb->len < len) {
seq += skb->len; seq += skb->len;
len -= skb->len; len -= skb->len;
@@ -333,6 +337,8 @@ static bool tls_strp_check_no_dup(struct tls_strparser *strp)
if (TCP_SKB_CB(skb)->seq != seq) if (TCP_SKB_CB(skb)->seq != seq)
return false; return false;
if (skb_cmp_decrypted(first, skb))
return false;
} }
return true; return true;
@@ -413,7 +419,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
return tls_strp_read_copy(strp, true); return tls_strp_read_copy(strp, true);
} }
if (!tls_strp_check_no_dup(strp)) if (!tls_strp_check_queue_ok(strp))
return tls_strp_read_copy(strp, false); return tls_strp_read_copy(strp, false);
strp->msg_ready = 1; strp->msg_ready = 1;