Commit 14c4be92 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller
Browse files

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: default avatarShai Amiram <samiram@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 210620ae
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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;
};

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,
				      const struct sk_buff *from)
{
+11 −5
Original line number Diff line number Diff line
@@ -317,15 +317,19 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
	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;
	struct sk_buff *skb;
	struct sk_buff *first, *skb;
	u32 seq;

	skb = skb_shinfo(strp->anchor)->frag_list;
	seq = TCP_SKB_CB(skb)->seq;
	first = skb_shinfo(strp->anchor)->frag_list;
	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) {
		seq += 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)
			return false;
		if (skb_cmp_decrypted(first, skb))
			return false;
	}

	return true;
@@ -413,7 +419,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
			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);

	strp->msg_ready = 1;