Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Paolo Abeni and committed by
David S. Miller
78352f73 e0e3070a

+16 -3
+13 -3
include/linux/udp.h
··· 51 51 * different encapsulation layer set 52 52 * this 53 53 */ 54 - gro_enabled:1; /* Can accept GRO packets */ 54 + gro_enabled:1, /* Request GRO aggregation */ 55 + accept_udp_l4:1, 56 + accept_udp_fraglist:1; 55 57 /* 56 58 * Following member retains the information to create a UDP header 57 59 * when the socket is uncorked. ··· 133 131 134 132 static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) 135 133 { 136 - return !udp_sk(sk)->gro_enabled && skb_is_gso(skb) && 137 - skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4; 134 + if (!skb_is_gso(skb)) 135 + return false; 136 + 137 + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && !udp_sk(sk)->accept_udp_l4) 138 + return true; 139 + 140 + if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist) 141 + return true; 142 + 143 + return false; 138 144 } 139 145 140 146 #define udp_portaddr_for_each_entry(__sk, list) \
+3
net/ipv4/udp.c
··· 2666 2666 2667 2667 case UDP_GRO: 2668 2668 lock_sock(sk); 2669 + 2670 + /* when enabling GRO, accept the related GSO packet type */ 2669 2671 if (valbool) 2670 2672 udp_tunnel_encap_enable(sk->sk_socket); 2671 2673 up->gro_enabled = valbool; 2674 + up->accept_udp_l4 = valbool; 2672 2675 release_sock(sk); 2673 2676 break; 2674 2677