net: bootp: Prevent out-of-bounds read in dhcp_message_type
dhcp_message_type() scans DHCP options looking for a 0xff end-of-options marker with no check that the scan pointer stays within the received packet. A server can send a crafted OFFER with no 0xff terminator and large option length fields, advancing the pointer past bp_vend[312] into adjacent heap memory. This is the same class of bug as CVE-2024-42040, which fixed the related bootp_process_vendor() call site. Fix it by adding an end parameter to dhcp_message_type() and checking that popt is lower than end. Signed-off-by: Francois Berder <fberder@outlook.fr> Reviewed-by: Jerome Forissier <jerome.forissier@arm.com>
This commit is contained in:
committed by
Jerome Forissier
parent
2b612de895
commit
f447887238
+4
-4
@@ -997,13 +997,13 @@ static void dhcp_packet_process_options(struct bootp_hdr *bp)
|
||||
}
|
||||
}
|
||||
|
||||
static int dhcp_message_type(unsigned char *popt)
|
||||
static int dhcp_message_type(unsigned char *popt, unsigned char *end)
|
||||
{
|
||||
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
|
||||
return -1;
|
||||
|
||||
popt += 4;
|
||||
while (*popt != 0xff) {
|
||||
while (popt < end && *popt != 0xff) {
|
||||
if (*popt == 53) /* DHCP Message Type */
|
||||
return *(popt + 2);
|
||||
if (*popt == 0) {
|
||||
@@ -1120,7 +1120,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
|
||||
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
|
||||
if (CONFIG_IS_ENABLED(UNIT_TEST) &&
|
||||
dhcp_message_type((u8 *)bp->bp_vend) == -1) {
|
||||
dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == -1) {
|
||||
debug("got BOOTP response; transitioning to BOUND\n");
|
||||
goto dhcp_got_bootp;
|
||||
}
|
||||
@@ -1149,7 +1149,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||
case REQUESTING:
|
||||
debug("DHCP State: REQUESTING\n");
|
||||
|
||||
if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
|
||||
if (dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == DHCP_ACK) {
|
||||
dhcp_got_bootp:
|
||||
dhcp_packet_process_options(bp);
|
||||
/* Store net params from reply */
|
||||
|
||||
Reference in New Issue
Block a user