From: Maxim Mikityanskiy From: Maxim Mikityanskiy Currently, gro_max_size and gro_ipv4_max_size can be set to values bigger than 65536, and GRO will happily aggregate UDP to the configured size (for example, with TCP traffic in VXLAN tunnels). However, udp_gro_complete uses the 16-bit length field in the UDP header to store the length of the aggregated packet. It leads to the packet truncation later in __udp4_lib_rcv. Fix this by storing 0 to the UDP length field and by restoring the real length from skb->len in __udp4_lib_rcv. Signed-off-by: Maxim Mikityanskiy --- net/ipv4/udp.c | 5 ++++- net/ipv4/udp_offload.c | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 0c40426628eb..0ac03f5596ac 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2643,7 +2643,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, { struct sock *sk = NULL; struct udphdr *uh; - unsigned short ulen; + unsigned int ulen; struct rtable *rt = skb_rtable(skb); __be32 saddr, daddr; struct net *net = dev_net(skb->dev); @@ -2667,6 +2667,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, goto short_packet; if (proto == IPPROTO_UDP) { + if (!ulen) + ulen = skb->len; + /* UDP validates ulen. */ if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen)) goto short_packet; diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index b1f3fd302e9d..1e7ed7718d7b 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -924,12 +924,15 @@ static int udp_gro_complete_segment(struct sk_buff *skb) int udp_gro_complete(struct sk_buff *skb, int nhoff, udp_lookup_t lookup) { - __be16 newlen = htons(skb->len - nhoff); + unsigned int newlen = skb->len - nhoff; struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); struct sock *sk; int err; - uh->len = newlen; + if (newlen <= GRO_LEGACY_MAX_SIZE) + uh->len = htons(newlen); + else + uh->len = 0; sk = INDIRECT_CALL_INET(lookup, udp6_lib_lookup_skb, udp4_lib_lookup_skb, skb, uh->source, uh->dest); -- 2.50.1