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

Commit 751aaf9f authored by Paolo Abeni's avatar Paolo Abeni Committed by Connor O'Brien
Browse files

UPSTREAM: udp: never accept GSO_FRAGLIST packets



Currently the UDP protocol delivers GSO_FRAGLIST packets to
the sockets without the expected segmentation.

This change addresses the issue introducing and maintaining
a couple of new fields to explicitly accept SKB_GSO_UDP_L4
or GSO_FRAGLIST packets. Additionally updates  udp_unexpected_gso()
accordingly.

UDP sockets enabling UDP_GRO stil keep accept_udp_fraglist
zeroed.

v1 -> v2:
 - use 2 bits instead of a whole GSO bitmask (Willem)

Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
(cherry picked from commit 78352f73dc5047f3f744764cc45912498c52f3c9)
Bug: 187129171
Signed-off-by: default avatarConnor O'Brien <connoro@google.com>
Change-Id: I79d90f403c10f83f21e3f99554b6fdbfc2cc60b0
parent 01228292
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -51,7 +51,9 @@ struct udp_sock {
					   * different encapsulation layer set
					   * this
					   */
			 gro_enabled:1;	/* Can accept GRO packets */
			 gro_enabled:1,	/* Request GRO aggregation */
			 accept_udp_l4:1,
			 accept_udp_fraglist:1;
	/*
	 * Following member retains the information to create a UDP header
	 * when the socket is uncorked.
@@ -131,8 +133,16 @@ static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,

static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb)
{
	return !udp_sk(sk)->gro_enabled && skb_is_gso(skb) &&
	       skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4;
	if (!skb_is_gso(skb))
		return false;

	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && !udp_sk(sk)->accept_udp_l4)
		return true;

	if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist)
		return true;

	return false;
}

#define udp_portaddr_for_each_entry(__sk, list) \
+3 −0
Original line number Diff line number Diff line
@@ -2595,9 +2595,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,

	case UDP_GRO:
		lock_sock(sk);

		/* when enabling GRO, accept the related GSO packet type */
		if (valbool)
			udp_tunnel_encap_enable(sk->sk_socket);
		up->gro_enabled = valbool;
		up->accept_udp_l4 = valbool;
		release_sock(sk);
		break;