udp: Validate UDP length in udp_gro_receive

In the previous commit we started using uh->len = 0 as a marker of a GRO
packet bigger than 65536 bytes. Filter out malformed packets coming from
the wire with len=0 at udp_gro_receive to exclude them from GRO.

Note that a similar check was present in udp_gro_receive_segment, but
not in the UDP socket gro_receive flow. By adding an early check to
udp_gro_receive, the check in udp_gro_receive_segment can be dropped.

Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260710134242.216538-6-alice.kernel@fastmail.im
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Alice Mikityanska
2026-07-10 16:42:38 +03:00
committed by Paolo Abeni
parent efbc1aa8ed
commit 8475a3efe6

View File

@@ -707,12 +707,8 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
return NULL;
}
/* Do not deal with padded or malicious packets, sorry ! */
ulen = udp_get_len_short(uh);
if (ulen <= sizeof(*uh) || ulen != skb_gro_len(skb)) {
NAPI_GRO_CB(skb)->flush = 1;
return NULL;
}
/* pull encapsulating udp header */
skb_gro_pull(skb, sizeof(struct udphdr));
@@ -782,8 +778,14 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
struct sk_buff *p;
struct udphdr *uh2;
unsigned int off = skb_gro_offset(skb);
unsigned int ulen;
int flush = 1;
/* Do not deal with padded or malicious packets, sorry! */
ulen = udp_get_len_short(uh);
if (ulen <= sizeof(*uh) || ulen != skb_gro_len(skb))
goto out;
/* We can do L4 aggregation only if the packet can't land in a tunnel
* otherwise we could corrupt the inner stream. Detecting such packets
* cannot be foolproof and the aggregation might still happen in some