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

Commit 4fb57e94 authored by Alexander Duyck's avatar Alexander Duyck Committed by Sean Tranchetti
Browse files

udp: Do not copy destructor if one is not present



This patch makes it so that if a destructor is not present we avoid trying
to update the skb socket or any reference counting that would be associated
with the NULL socket and/or descriptor. By doing this we can support
traffic coming from another namespace without any issues.

Change-Id: I61155db99242c0c39f0a19f7a455c0a90d1ac8f3
CRs-Fixed: 2351793
Acked-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Git-commit: 04d55b25
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git


Signed-off-by: default avatarSean Tranchetti <stranche@codeaurora.org>
parent e0914a57
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
	struct sk_buff *segs, *seg;
	struct udphdr *uh;
	unsigned int mss;
	bool copy_dtor;
	__sum16 check;
	__be16 newlen;

@@ -205,11 +206,13 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
	skb_pull(gso_skb, sizeof(*uh));

	/* clear destructor to avoid skb_segment assigning it to tail */
	WARN_ON_ONCE(gso_skb->destructor != sock_wfree);
	copy_dtor = gso_skb->destructor == sock_wfree;
	if (copy_dtor)
		gso_skb->destructor = NULL;

	segs = skb_segment(gso_skb, features);
	if (unlikely(IS_ERR_OR_NULL(segs))) {
		if (copy_dtor)
			gso_skb->destructor = sock_wfree;
		return segs;
	}
@@ -229,9 +232,11 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
	check = csum16_add(csum16_sub(uh->check, uh->len), newlen);

	for (;;) {
		if (copy_dtor) {
			seg->destructor = sock_wfree;
			seg->sk = sk;
			sum_truesize += seg->truesize;
		}

		if (!seg->next)
			break;
@@ -263,8 +268,9 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
		uh->check = gso_make_checksum(seg, ~check) ? : CSUM_MANGLED_0;

	/* update refcount for the packet */
	refcount_add(sum_truesize - gso_skb->truesize, &sk->sk_wmem_alloc);

	if (copy_dtor)
		refcount_add(sum_truesize - gso_skb->truesize,
			     &sk->sk_wmem_alloc);
	return segs;
}
EXPORT_SYMBOL_GPL(__udp_gso_segment);