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 <shahriyar@byteray.co.uk> Acked-by: Jerome Forissier <jerome.forissier@arm.com>
This commit is contained in:
committed by
Jerome Forissier
parent
85d82c5232
commit
04ca915d5b
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user