From 04ca915d5bf39dda5d1bce62d04d2b59d293c5b9 Mon Sep 17 00:00:00 2001 From: Shahriyar Jalayeri Date: Tue, 28 Jul 2026 08:50:07 +0200 Subject: net: fix out-of-bounds write in IP fragment reassembly __net_defragment() reassembles IP fragments into the static buffer pkt_buff[CONFIG_NET_MAXDEFRAG]. The bounds check if (start + len > IP_MAXUDP) return NULL; only covers the fragment data copy. The split-hole and move-hole branches additionally write an 8-byte struct hole via "*newh = *h" at newh = thisfrag + len / 8, which can land up to sizeof(struct hole) bytes past the end of pkt_buff. A single fragment with a non-zero fragment offset and the More-Fragments flag set reaches this path, so a crafted fragment received during netboot overflows the buffer. Reject any fragment whose trailing hole descriptor would fall outside pkt_buff. Signed-off-by: Shahriyar Jalayeri Acked-by: Jerome Forissier --- net/net.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/net.c b/net/net.c index 61c5a6ef6c4..71666eb1113 100644 --- a/net/net.c +++ b/net/net.c @@ -1076,6 +1076,8 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) } else if (h >= thisfrag) { /* overlaps with initial part of the hole: move this hole */ newh = thisfrag + (len / 8); + if ((uchar *)(newh + 1) > pkt_buff + IP_PKTSIZE) + return NULL; /* hole descriptor would overflow pkt_buff */ *newh = *h; h = newh; if (h->next_hole) @@ -1088,6 +1090,8 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) } else { /* fragment sits in the middle: split the hole */ newh = thisfrag + (len / 8); + if ((uchar *)(newh + 1) > pkt_buff + IP_PKTSIZE) + return NULL; /* hole descriptor would overflow pkt_buff */ *newh = *h; h->last_byte = start; h->next_hole = (newh - payload); -- cgit v1.3.1