diff options
| author | Hauke Mehrtens | 2026-05-23 12:05:18 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-18 00:34:57 +0000 |
| commit | 6907f28f9ddeef9f69f5ee10bbc9ba8adc0ef57f (patch) | |
| tree | 1e0cd3ac3fb3f756ecec9655dc618a3e3a1b4a78 | |
| parent | edf2e523b7ae23830a7377343b66c7675c7703c7 (diff) | |
| download | odhcpd-6907f28f9ddeef9f69f5ee10bbc9ba8adc0ef57f.tar.gz | |
dhcpv6: fix out-of-bounds read in self-loop detection memcmp
The "talk to ourself" guard in handle_client_request() compares the
configured server DUID against the received client DUID. Both length
fields are stored in network byte order (set via htons()), but the
memcmp() length argument was passed as the htons-encoded value rather
than the host-order length. On little-endian hosts this multiplies the
true length by 256, so for a typical 14-byte DUID the memcmp reads
3584 bytes from a 130-byte stack buffer, an attacker-reachable OOB
read of stack memory.
Use ntohs(dest.serverid_length) so memcmp gets the actual DUID length.
Assisted-by: Claude:claude-opus-4-7
Link: https://github.com/openwrt/odhcpd/pull/401
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
(cherry picked from commit ed38cffa927d5fd450d20bfd3f7fb8d8e8fff301)
| -rw-r--r-- | src/dhcpv6.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c index a211b25..868740f 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -715,10 +715,10 @@ static void handle_client_request(void *addr, void *data, size_t len, } } - if (dest.serverid_length == clientid.len && - !memcmp(clientid.buf, dest.serverid_buf, dest.serverid_length)) { + if (dest.serverid_length == clientid.len && + !memcmp(clientid.buf, dest.serverid_buf, ntohs(dest.serverid_length))) { /* Bail if we are in a network loop where we talk with ourself */ - return; + return; } if (!IN6_IS_ADDR_MULTICAST((struct in6_addr *)dest_addr) && iov[IOV_NESTED].iov_len == 0 && |