ic_bootp_recv() accepts an IP packet whose total length exceeds its UDP
datagram length. This is valid at the IP layer, but DHCP/BOOTP options
belong to the UDP payload. The option parser nevertheless uses the IP
total length as its end boundary.
Consequently, an on-link attacker that can race a boot-time DHCP exchange
can put DHCP options after the declared UDP payload and have ipconfig
consume them. A QEMU/KVM reproduction with ip=dhcp accepted a forged
DHCPOFFER/DHCPACK with an IP total length of 290 and UDP length of 248;
the tail supplied a netmask and an off-link gateway, causing boot-time
network configuration to fail.
Use the UDP datagram end as the parser boundary. The receiver already
verifies that the UDP datagram lies within the IP packet, so this retains
normal valid DHCP/BOOTP parsing while excluding the IP-only tail.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Yizhou Zhao <redacted>
Reported-by: Yuxiang Yang <redacted>
Reported-by: Ao Wang <redacted>
Reported-by: Xuewei Feng <redacted>
Reported-by: Qi Li <redacted>
Reported-by: Ke Xu <redacted>
Assisted-by: Claude-Code:GLM-5.2-special
Signed-off-by: Yizhou Zhao <redacted>
---diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index a35ffedacc7c..192874623a24 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1068,7 +1068,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
/* Parse extensions */
if (ext_len >= 4 &&
!memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
- u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
+ u8 *end = (u8 *)b + sizeof(struct iphdr) + ntohs(b->udph.len);
u8 *ext;
#ifdef IPCONFIG_DHCP--
2.47.3