mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-01 13:20:36 +00:00
lease: check parse_hex() return value before use as length
parse_hex() returns -1 on malformed input. Three call sites in
read_leases() used the return value directly as a length argument
without checking for the error sentinel:
opt_len → lease_set_vendorclass() / lease_set_agent_id()
whine_malloc(-1) attempts a ~4 GB allocation, likely
crashing the process.
hw_len → lease_set_hwaddr()
memcpy(lease->hwaddr, hwaddr, (size_t)-1) performs an
~18 EB write, causing an immediate crash.
clid_len → lease_set_hwaddr() (same path as hw_len)
Exploitation requires a corrupted or attacker-controlled lease file;
it is not directly network-triggerable. However, any process that can
write to the lease file (e.g. a compromised helper) can crash or
potentially gain code execution in the dnsmasq process at next startup
or lease-file re-read.
Fix: mirror the existing duid path (which already guards its
parse_hex call) by checking for < 0. For opt_len, skip the record
(continue) to match the "invalid line" behaviour. For hw_len and
clid_len, treat the failure as a zero-length field so the lease is
still created with the correct address.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
0630a45ae1
commit
cd04c0ce20
1 file changed
+10
-2
+10
-2
@@ -73,7 +73,9 @@ static int read_leases(time_t now, FILE *leasestream)
|
||||
if (lease)
|
||||
{
|
||||
opt_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
||||
|
||||
if (opt_len < 0)
|
||||
continue;
|
||||
|
||||
if (strcmp(daemon->dhcp_buff3, "vendorclass") == 0)
|
||||
lease_set_vendorclass(lease, (unsigned char *)daemon->packet, opt_len);
|
||||
else if (strcmp(daemon->dhcp_buff3, "agent-info") == 0)
|
||||
@@ -99,6 +101,8 @@ static int read_leases(time_t now, FILE *leasestream)
|
||||
|
||||
|
||||
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
|
||||
if (hw_len < 0)
|
||||
hw_len = 0;
|
||||
/* For backwards compatibility, no explicit MAC address type means ether. */
|
||||
if (hw_type == 0 && hw_len != 0)
|
||||
hw_type = ARPHRD_ETHER;
|
||||
@@ -131,7 +135,11 @@ static int read_leases(time_t now, FILE *leasestream)
|
||||
die (_("too many stored leases"), NULL, EC_MISC);
|
||||
|
||||
if (strcmp(daemon->packet, "*") != 0)
|
||||
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
||||
{
|
||||
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
||||
if (clid_len < 0)
|
||||
clid_len = 0;
|
||||
}
|
||||
|
||||
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
|
||||
hw_len, hw_type, clid_len, now, 0);
|
||||
|
||||
Reference in new issue
Block a user