CVE-2026-79980 in Zephyr
Summary
by MITRE • 10/23/2026
The DHCPv4 client in subsys/net/lib/dhcpv4/dhcpv4.c maintained its transaction identifier (iface->config.dhcpv4.xid) as a counter rather than as a per-transaction random value. It was seeded once with sys_rand32_get() in dhcpv4_start_internal(), incremented by one in dhcpv4_send_discover() and dhcpv4_send_decline(), and never changed by dhcpv4_send_request() — so every RENEWING and REBINDING exchange reused, unchanged, the identifier that had already appeared on the wire in the broadcast DHCPDISCOVER at boot, and where the identifier did move it moved predictably by one. RFC 2131 4.1 requires a single identifier per transaction, chosen so that clients are unlikely to collide.
This identifier is the client's only unpredictable reply-validation token. net_dhcpv4_input() accepts a BOOTP reply on op, a matching xid, and a matching chaddr (the interface MAC, which is public); the UDP callback is registered with a wildcard remote address and port, and no server-identifier or source-address check is applied. An attacker who learns one identifier — for example any host on the same segment that sees the broadcast DHCPDISCOVER, or a DHCP server or relay on a network the device previously joined — therefore retains a valid token for the device's whole uptime, and can predict the identifiers of later exchanges, without having to observe the unicast renew traffic or race the legitimate server.
A forged reply that passes those checks has effect regardless of client state, because dhcpv4_parse_options() applies its side effects before the state machine gate in dhcpv4_handle_reply(): the router option calls net_if_ipv4_set_gw() and the DNS option calls dns_resolve_reconfigure(). A single accepted datagram can thus repoint the device's default gateway and resolvers at attacker-controlled addresses, redirecting its traffic; during RENEWING or REBINDING a forged DHCPACK re-binds the lease with attacker-chosen parameters and a forged DHCPNAK removes the address and restarts configuration.
The fix draws a fresh sys_rand32_get() value at each point where a transaction begins — entering SELECTING, RENEWING and REBINDING, and at the INIT/INIT-REBOOT entry taken when an interface with a lease goes down — while REQUESTING and DECLINE keep the identifier of the exchange they belong to, as RFC 2131 requires. As a side effect the client also no longer discards a slow server's offer after retransmitting a discover, and the initial-discover backoff now draws its own randomness instead of deriving it from the identifier.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 10/23/2026
The DHCPv4 client implementation in subsys/net/lib/dhcpv4/dhcpv4.c contains a critical vulnerability stemming from an insufficiently random transaction identifier generation mechanism. Instead of generating a cryptographically secure, per-transaction random value as recommended by RFC 2131 section 4.1, the system maintained its transaction identifier (xid) as a simple counter seeded once with sys_rand32_get() during initialization. This design flaw resulted in predictable and reusable identifiers across multiple DHCP exchanges. Specifically, while the xid was incremented for DISCOVER and DECLINE messages, it remained unchanged during RENEWING and REBINDING phases. Consequently, every renewal or rebinding exchange reused the same identifier that had been broadcasted publicly at boot time, creating a persistent pattern that attackers could easily exploit without needing to observe subsequent unicast traffic in real-time.
This lack of randomness fundamentally undermines the security model for validating DHCP replies. The net_dhcpv4_input function accepts BOOTP responses based solely on matching operation codes, transaction identifiers, and client hardware addresses (chaddr), which is typically a public MAC address. Furthermore, the UDP callback was registered with wildcard remote addresses and ports, lacking any verification of server-identifier or source IP addresses. An attacker positioned on the same network segment can observe the initial broadcast DHCPDISCOVER to capture the starting xid value. Because subsequent identifiers are either reused unchanged or incremented predictably by one, an adversary retains a valid token for the duration of the device's uptime. This allows the attacker to forge responses that will be accepted as legitimate without needing to race against the actual DHCP server or monitor private unicast communications.
The operational impact of this vulnerability is severe, enabling both traffic redirection and denial-of-service attacks through forged reply manipulation. The dhcpv4_parse_options function applies side effects such as setting the default gateway via net_if_ipv4_set_gw() and reconfiguring DNS resolvers via dns_resolve_reconfigure before the state machine gate in dhcpv4_handle_reply() can validate the context of the transaction. This ordering flaw means that a single accepted datagram can immediately repoint the device's network configuration to attacker-controlled addresses, effectively hijacking all outbound traffic. During RENEWING or REBINDING states, a forged DHCPACK can re-bind the lease with malicious parameters, while a forged DHCPNAK can forcibly remove the IP address and restart the configuration process, causing service disruption.
This vulnerability aligns with CWE-330: Use of Insufficiently Random Values, as the transaction identifier fails to provide adequate unpredictability for its security function. It also relates to CWE-295: Improper Certificate Validation in a broader sense regarding trust establishment and MITM6 or DHCP spoofing techniques often categorized under ATT&CK T1487 (Network Service Scanning) and T1040 (Network Sniffing). The exploitation does not require complex network manipulation beyond basic packet injection on the local segment, making it accessible to low-privilege attackers with physical or wireless access.
The remediation strategy involves generating a fresh random value using sys_rand32_get() at every point where a new transaction begins, including entry into SELECTING, RENEWING, and REBINDING states, as well as during INIT/INIT-REBOOT transitions when an interface with a lease goes down. The implementation ensures that REQUESTING and DECLINE phases retain the identifier of their respective exchanges in compliance with RFC 2131 requirements. Additionally, the fix addresses related issues by preventing the discarding of slow server offers after retransmission and ensuring that initial-discover backoff mechanisms derive randomness independently from the transaction identifier, thereby enhancing overall protocol robustness against prediction attacks.