CVE-2026-29004 Overview
CVE-2026-29004 is a heap buffer overflow vulnerability in BusyBox affecting the DHCPv6 client (udhcpc6) DNS_SERVERS option handler. The flaw exists in networking/udhcp/d6_dhcpc.c and stems from incorrect heap buffer allocation calculations in the option_to_env() function. Network-adjacent attackers can send a crafted DHCPv6 response containing a malformed D6_OPT_DNS_SERVERS option to trigger memory corruption. Successful exploitation can cause denial of service or arbitrary code execution on embedded systems lacking heap hardening protections. The vulnerability is patched in BusyBox commit 42202bf.
Critical Impact
Network-adjacent attackers on the same link can corrupt heap memory in udhcpc6, enabling denial of service or arbitrary code execution on embedded Linux devices commonly running BusyBox.
Affected Products
- BusyBox versions prior to commit 42202bf
- Embedded Linux systems using udhcpc6 (DHCPv6 client) for IPv6 configuration
- IoT devices, routers, and appliances bundling vulnerable BusyBox builds
Discovery Timeline
- 2026-05-04 - CVE-2026-29004 published to NVD
- 2026-05-06 - Last updated in NVD database
Technical Details for CVE-2026-29004
Vulnerability Analysis
The vulnerability resides in the option_to_env() function within networking/udhcp/d6_dhcpc.c, which processes DHCPv6 options received from a server. When handling the D6_OPT_DNS_SERVERS option, the function allocates a heap buffer to construct a dns= environment variable string containing the IPv6 addresses returned by the server.
The original code computed the allocation size as 4 + addrs * 40 - 1, which is one byte short of the actual data written. Each IPv6 address consumes 39 characters plus a separator, plus the dns= prefix and a trailing NUL byte. This off-by-one error in the allocation formula causes a heap buffer overflow when the formatted string is written via stpcpy() and sprint_nip6().
The issue is classified as a heap-based buffer overflow [CWE-122]. On embedded systems without heap hardening, allocator metadata corruption can be leveraged for arbitrary code execution.
Root Cause
The root cause is an arithmetic error in the heap allocation size calculation. The expression 4 + addrs * 40 - 1 underestimates the required buffer by one byte. Additionally, the loop control logic relied on a truthiness check (while (addrs--)) that interacted unsafely with the addrs value derived from option[3] >> 4, which is attacker-controlled via the DHCPv6 response.
Attack Vector
An attacker on the same local link as the victim sends a crafted DHCPv6 reply with a malformed D6_OPT_DNS_SERVERS option. The option[3] length byte controls the number of addresses parsed, allowing the attacker to influence both the allocation size and the volume of bytes written into the undersized buffer. No authentication or user interaction is required.
// Patch from BusyBox commit 42202bf - networking/udhcp/d6_dhcpc.c
// Fix: correct buffer size calculation and loop termination
addrs = option[3] >> 4;
/* Setup environment variable */
- *new_env() = dlist = xmalloc(4 + addrs * 40 - 1);
+ *new_env() = dlist = xmalloc(4 + addrs * 40 + 1);
dlist = stpcpy(dlist, "dns=");
option_offset = 0;
- while (addrs--) {
+ while (addrs-- != 0) {
sprint_nip6(dlist, option + 4 + option_offset);
dlist += 39;
option_offset += 16;
- if (addrs)
+ if (addrs != 0)
*dlist++ = ' ';
}
Source: BusyBox commit 42202bf
A related hardening patch validates the size of the D6_OPT_IAPREFIX option to ensure the payload contains the full prefix structure:
// Patch from BusyBox commit d368f3f - additional D6_OPT_IAPREFIX size check
- /* Make sure payload contains an address */
- if (option[3] < 24)
+ /* Make sure payload exists */
+ if (option[3] < (16 + 4 + 4))
break;
sprint_nip6(ipv6str, option + 4);
Source: BusyBox commit d368f3f
Detection Methods for CVE-2026-29004
Indicators of Compromise
- Unexpected udhcpc6 process crashes or SIGSEGV events on embedded devices
- Anomalous DHCPv6 Reply messages on local segments containing oversized or malformed D6_OPT_DNS_SERVERS (option code 23) payloads
- IPv6 address counts in D6_OPT_DNS_SERVERS that exceed normal operational baselines
- Rogue DHCPv6 servers advertising on networks where they should not be present
Detection Strategies
- Inspect DHCPv6 traffic with packet brokers or IDS signatures looking for malformed option lengths in option type 23
- Monitor BusyBox build manifests in firmware images and flag versions predating commit 42202bf
- Correlate udhcpc6 crash logs with recent DHCPv6 lease renewals to identify exploitation attempts
Monitoring Recommendations
- Enable DHCPv6 snooping on managed switches to suppress unauthorized DHCPv6 servers
- Centralize syslog from embedded devices and alert on udhcpc6 abnormal terminations
- Track network neighbor changes and unexpected Router Advertisement or DHCPv6 server appearances
How to Mitigate CVE-2026-29004
Immediate Actions Required
- Inventory all embedded devices, IoT systems, and appliances using BusyBox and identify those running udhcpc6
- Update BusyBox to a build that includes commit 42202bf or rebuild from patched source
- Restrict DHCPv6 traffic to trusted servers using DHCPv6 snooping or segment-level filtering
- Disable IPv6 or udhcpc6 on devices that do not require DHCPv6 address assignment
Patch Information
The vulnerability is fixed by BusyBox commit 42202bf, which corrects the heap allocation calculation in option_to_env() from xmalloc(4 + addrs * 40 - 1) to xmalloc(4 + addrs * 40 + 1) and tightens the loop termination check. Vendors of embedded Linux distributions should integrate this commit and rebuild firmware images. Refer to the VulnCheck Security Advisory and BusyBox project site for additional context.
Workarounds
- Disable the DHCPv6 client by removing udhcpc6 from device init scripts where IPv6 address autoconfiguration is unused
- Configure stateless address autoconfiguration (SLAAC) only and block DHCPv6 traffic at the network edge
- Apply RA Guard and DHCPv6 Guard on access switches to prevent rogue server messages from reaching clients
# Example: block inbound DHCPv6 server traffic (UDP/547) at the host
ip6tables -A INPUT -p udp --sport 547 --dport 546 -m conntrack \
--ctstate NEW -j DROP
# Example: disable udhcpc6 in BusyBox-based init (OpenWrt-style)
uci set network.wan6.proto='static'
uci commit network
/etc/init.d/network restart
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


