From 45771dc92ccfd091a28c4ed5519f4020b447be84 Mon Sep 17 00:00:00 2001 From: Michalis Vasileiadis Date: Sat, 30 May 2026 15:58:52 +0100 Subject: [PATCH] Fix OOB writes in contrib/leasequesry/leasequery.c Thanks to Michalis Vasileiadis for spotting this. print_mac() writes each MAC byte to its output buffer with unbounded sprintf and is called from main() with pkt.header.hlen straight out of a BOOTREPLY. hlen is an attacker-controlled uint8_t (up to 255), each byte expands to up to 3 chars, and the destination is a 500-byte stack buffer. A malicious leasequery server that echoes the client's transaction ID and replies with DHCPLEASEACTIVE and an oversized hlen overflows that stack buffer. The patch caps len inside print_mac at DHCP_CHADDR_MAX (16), which is the actual size of chaddr in the BOOTP header and an upper bound on any legitimate hardware-address length. The other in-file caller of print_mac already clamps its length argument to 14 before the call, so this change is local to the vulnerable path. --- contrib/leasequery/leasequery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/contrib/leasequery/leasequery.c b/contrib/leasequery/leasequery.c index 5d844ee..481b87c 100644 --- a/contrib/leasequery/leasequery.c +++ b/contrib/leasequery/leasequery.c @@ -331,9 +331,15 @@ static char *print_mac(char *buff, unsigned char *mac, int len) if (len == 0) sprintf(p, ""); else - for (i = 0; i < len; i++) - p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":"); - + { + /* Server-controlled lengths (e.g. BOOTREPLY hlen) must not be trusted + to fit the destination buffer; cap at the actual chaddr field size. */ + if (len > DHCP_CHADDR_MAX) + len = DHCP_CHADDR_MAX; + for (i = 0; i < len; i++) + p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":"); + } + return buff; }