ANT-2026-PCBAKVPB · dnsmasq
heap-buffer-overflow high
CVE-2026-4892 GHSA-m62j-63mf-xr95
Severity Claude high · Security research firm high · Maintainer high
Discovered by an unreleased Anthropic model
Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Trail of Bits.
ANT-2026-PCBAKVPB: Heap overflow in privileged helper via oversized DHCPv6 client identifier
In dnsmasq's privileged script helper (helper.c:265-270), each byte of the DHCP client-ID is hex-encoded with sprintf into daemon->packet, a ~2267-byte buffer allocated at startup and inherited via fork(). DHCPv6 option lengths are 16-bit and state->clid_len is taken from the wire at rfc3315.c:338 with no upper bound, then flows unchanged through lease_set_hwaddr() and queue_script() to the helper. A local-network attacker sends a single DHCPv6 SOLICIT with RAPID_COMMIT and a ~1200-byte OPTION6_CLIENT_ID (fits in one unfragmented IPv6 frame); when the lease script event fires, the helper writes ~3599 bytes into the 2267-byte buffer. The attacker controls the overflow length and the hex-digit content, corrupting the heap of a process that runs as root by default.
Target
Project: dnsmasq
Version: commit b95d5a25777cc8910d2c2a921c68c778a3b30498 (still present at HEAD)
Location: src/helper.c:265
Technical Details
Sink confirmed via ASAN: a harness allocating daemon->packet exactly as dnsmasq.c:128-129 does (PACKETSZ+MAXDNAME+RRFIXEDSZ = 1547 bytes at default edns_pktsz) and running the exact helper.c:265-270 hex-encode loop with clid_len=800 produced 'AddressSanitizer: heap-buffer-overflow … WRITE of size 3 … 0 bytes after 1547-byte region allocated by safe_malloc'. Source path verified statically: rfc3315.c:338 assigns state->clid_len = opt6_len(opt) with no upper bound; lease_set_hwaddr() (lease.c:992) stores it unchecked; queue_script() (helper.c:794/809) forwards it to the helper pipe unchanged. The helper inherits daemon->packet via fork(). Overflow threshold is clid_len ≥ ceil((bufsz+1)/3) ≈ 516 at defaults — well within the 16-bit DHCPv6 option length. Did not stand up a full DHCPv6 transaction in the time box, hence medium confidence on end-to-end reachability (requires --dhcp-script configured).
Crash trace (truncated — full trace in attached crash.log):
daemon->packet size = 1547 (PACKETSZ=512 MAXDNAME=1025 RRFIXEDSZ=10)
=================================================================
==17==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x51b000000d8b at pc 0xffff86e829d4 bp 0xffffc5315490 sp 0xffffc5315530
WRITE of size 3 at 0x51b000000d8b thread T0
#0 0xffff86e829d0 in vsprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1671
#1 0xffff86e83cf0 in sprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1714
#2 0xaaaab6b5ca6c in main /build/harness_400509.c:35
#3 0xffff863c2258 (/lib/aarch64-linux-gnu/libc.so.6+0x22258) (BuildId: 45918bc10b33fd96afc550c98de062dccdf44328)
#4 0xffff863c2338 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x22338) (BuildId: 45918bc10b33fd96afc550c98de062dccdf44328)
#5 0xaaaab6b5c5ec in _start (/build/h509+0x24c5ec) (BuildId: 59c1c64e9de91afd8fd09c5c0f7cb8edeff03a60)
allocated by thread T0 here:
#0 0xffff86ea9e4c in calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0xaaaab6cbe2bc in safe_malloc /build/dnsmasq/src/util.c:321
#2 0xaaaab6b5c7bc in main /build/harness_400509.c:21
#3 0xffff863c2258 (/lib/aarch64-linux-gnu/libc.so.6+0x22258) (BuildId: 45918bc10b33fd96afc550c98de062dccdf44328)
#4 0xffff863c2338 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x22338) (BuildId: 45918bc10b33fd96afc550c98de062dccdf44328)
#5 0xaaaab6b5c5ec in _start (/build/h509+0x24c5ec) (BuildId: 59c1c64e9de91afd8fd09c5c0f7cb8edeff03a60)
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1671 in vsprintf
Reproduction
- Craft a DHCPv6 SOLICIT containing OPTION6_RAPID_COMMIT, a minimal IA_TA (4-byte header + 4-byte IAID), and OPTION6_CLIENT_ID with a ≥756-byte (e.g. 1200-byte) payload
- Send it to the dnsmasq DHCPv6 port; packet fits in a single 1280-byte-MTU IPv6 frame
- RAPID_COMMIT path (rfc3315.c:654-660) sets lease_allocate=1; server allocates an address and stores clid/clid_len verbatim in the lease
- do_script_run() fires and queue_script() pipes clid_len to the helper child
- Helper reads data.clid_len and runs the sprintf hex-encode loop at helper.c:265-270, writing ~3×clid_len bytes into the fixed daemon->packet buffer and overflowing it by ~1332 bytes
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-PCBAKVPB.
Reference: ANT-2026-PCBAKVPB
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Triage and disclosure were performed by Trail of Bits.
- Verdict
- true positive
- Severity
- high
Dates from discovery through public reveal.
- 2026-04-08 Reported to tracker
- 2026-05-07 Sent to maintainer
- 2026-05-09 Maintainer acknowledged
- 2026-05-09 Patch released
- 2026-08-17 Publicly revealed
SHA-3-512 hash:
11a65d2d8b73e1b60aecd4aa985a653c77e1870999845708ab73eb335b44073062498a75e0adff81fdda190aa5e9610c21c27d36961cc01f8493cf85f7e3fa81
Committed 2026-05-07 00:02 PT
Revealed 2026-08-17 10:47 PT
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-PCBAKVPB",
"bug_class": "Heap-buffer-overflow",
"claude_severity": "high",
"commit_sha": null,
"created_at": "2026-04-09T05:32:58+00:00",
"description": "In dnsmasq's privileged script helper (helper.c:265-270), each byte of the DHCP client-ID is hex-encoded with sprintf into daemon->packet, a ~2267-byte buffer allocated at startup and inherited via fork(). DHCPv6 option lengths are 16-bit and state->clid_len is taken from the wire at rfc3315.c:338 with no upper bound, then flows unchanged through lease_set_hwaddr() and queue_script() to the helper. A local-network attacker sends a single DHCPv6 SOLICIT with RAPID_COMMIT and a ~1200-byte OPTION6_CLIENT_ID (fits in one unfragmented IPv6 frame); when the lease script event fires, the helper writes ~3599 bytes into the 2267-byte buffer. The attacker controls the overflow length and the hex-digit content, corrupting the heap of a process that runs as root by default.",
"discovered_at": null,
"location": "src/helper.c:265",
"poc_sha256": null,
"preimage_version": 1,
"project": "dnsmasq",
"reproduction": [
"1. Craft a DHCPv6 SOLICIT containing OPTION6_RAPID_COMMIT, a minimal IA_TA (4-byte header + 4-byte IAID), and OPTION6_CLIENT_ID with a ≥756-byte (e.g. 1200-byte) payload",
"2. Send it to the dnsmasq DHCPv6 port; packet fits in a single 1280-byte-MTU IPv6 frame",
"3. RAPID_COMMIT path (rfc3315.c:654-660) sets lease_allocate=1; server allocates an address and stores clid/clid_len verbatim in the lease",
"4. do_script_run() fires and queue_script() pipes clid_len to the helper child",
"5. Helper reads data.clid_len and runs the sprintf hex-encode loop at helper.c:265-270, writing ~3×clid_len bytes into the fixed daemon->packet buffer and overflowing it by ~1332 bytes"
],
"technical_details": "Sink confirmed via ASAN: a harness allocating daemon->packet exactly as dnsmasq.c:128-129 does (PACKETSZ+MAXDNAME+RRFIXEDSZ = 1547 bytes at default edns_pktsz) and running the exact helper.c:265-270 hex-encode loop with clid_len=800 produced 'AddressSanitizer: heap-buffer-overflow … WRITE of size 3 … 0 bytes after 1547-byte region allocated by safe_malloc'. Source path verified statically: rfc3315.c:338 assigns state->clid_len = opt6_len(opt) with no upper bound; lease_set_hwaddr() (lease.c:992) stores it unchecked; queue_script() (helper.c:794/809) forwards it to the helper pipe unchanged. The helper inherits daemon->packet via fork(). Overflow threshold is clid_len ≥ ceil((bufsz+1)/3) ≈ 516 at defaults — well within the 16-bit DHCPv6 option length. Did not stand up a full DHCPv6 transaction in the time box, hence medium confidence on end-to-end reachability (requires --dhcp-script configured).",
"title": "Heap overflow in privileged helper via oversized DHCPv6 client identifier",
"vendor_severity": "high"
}