diff options
| author | Paul HENRYS <[email protected]> | 2025-10-09 17:43:28 +0200 |
|---|---|---|
| committer | Jerome Forissier <[email protected]> | 2025-10-22 14:28:33 +0200 |
| commit | 81e5708cc2c865df606e49aed5415adb2a662171 (patch) | |
| tree | e3ab086d516eb3d75920f01532d4146f8973e6cf /net | |
| parent | 34369d34e413ac32a131dd144b55ad04873e4854 (diff) | |
net: bootp: Prevent buffer overflow to avoid leaking the RAM content
CVE-2024-42040 describes a possible buffer overflow when calling
bootp_process_vendor() in bootp_handler() since the total length
of the packet is passed to bootp_process_vendor() without being
reduced to len-(offsetof(struct bootp_hdr,bp_vend)+4).
The packet length is also checked against its minimum size to avoid
reading data from struct bootp_hdr outside of the packet length.
Signed-off-by: Paul HENRYS <[email protected]>
Signed-off-by: Philippe Reynes <[email protected]>
Diffstat (limited to 'net')
| -rw-r--r-- | net/bootp.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/net/bootp.c b/net/bootp.c index a28d11cb368..64fca9a42d9 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -379,6 +379,14 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip, debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n", src, dest, len, sizeof(struct bootp_hdr)); + /* Check the minimum size of a BOOTP packet is respected. + * A BOOTP packet is between 300 bytes and 576 bytes big + */ + if (len < offsetof(struct bootp_hdr, bp_vend) + 64) { + printf("Error: got an invalid BOOTP packet (len=%u)\n", len); + return; + } + bp = (struct bootp_hdr *)pkt; /* Filter out pkts we don't want */ @@ -396,7 +404,8 @@ static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip, /* Retrieve extended information (we must parse the vendor area) */ if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - bootp_process_vendor((uchar *)&bp->bp_vend[4], len); + bootp_process_vendor((uchar *)&bp->bp_vend[4], len - + (offsetof(struct bootp_hdr, bp_vend) + 4)); net_set_timeout_handler(0, (thand_f *)0); bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop"); |
