Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbef9478 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents b2a20fd0 eb3d38d5
Loading
Loading
Loading
Loading
+28 −11
Original line number Original line Diff line number Diff line
@@ -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,25 +628,42 @@ 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_pagelen(skb) > offset) {
		copy = min_t(int, skb_pagelen(skb) - offset, data_len);


		if (skb->decrypted)
		if (skb->decrypted)
			skb_store_bits(skb, offset, buf, copy);
			skb_store_bits(skb, offset, buf, copy);


		offset += copy;
		offset += copy;
		buf += copy;
		buf += copy;
	}


	pos = skb_pagelen(skb);
	skb_walk_frags(skb, skb_iter) {
	skb_walk_frags(skb, skb_iter) {
		copy = min_t(int, skb_iter->len,
		int frag_pos;
			     rxm->full_len - offset + rxm->offset -

			     TLS_CIPHER_AES_GCM_128_TAG_SIZE);
		/* 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)
		if (skb_iter->decrypted)
			skb_store_bits(skb_iter, offset, buf, copy);
			skb_store_bits(skb_iter, frag_pos, buf, copy);


		offset += copy;
		offset += copy;
		buf += copy;
		buf += copy;
done_with_frag:
		pos += skb_iter->len;
	}
	}


free_buf:
free_buf: