[Dnsmasq-discuss] BUG:Heap buffer overflow in src/forward.c due to incorrect pointer arithmetic (CWE-122)
Critizero Chen
critizero at gmail.com
Mon Mar 23 02:34:07 UTC 2026
Dear Simon and the dnsmasq community,
I have identified a critical heap buffer overflow vulnerability in the
current master branch (regression introduced in commit e5e8c14 during EDNS0
refactoring). This flaw could lead to a Denial of Service (DoS) or
potentially Remote Code Execution (RCE).
Summary
The issue lies in src/forward.c where the packet boundary limit pointer is
calculated. The code incorrectly uses pointer arithmetic on struct
dns_header * instead of casting to unsigned char * first. Since sizeof(struct
dns_header) is 12 bytes, the limit pointer is inflated by a factor of 12,
allowing add_resource_record() to write far beyond the allocated heap
buffer.
Details & Root Cause
In src/forward.c, several lines calculate the buffer limit as follows:
(unsigned
char *)(header + daemon->edns_pktsz) or (char *)(header + replylimit)
Because header is of type struct dns_header *, C pointer logic scales the
addition.
-
*Intended:* header + 512 bytes
-
*Actual:* header + (512 * 12) = header + 6144 bytes
However, the buffer daemon->packet is typically allocated around *1547 -
2267 bytes*.
Impacted Lines (Current Master)
-
src/forward.c:517
-
src/forward.c:592
-
src/forward.c:600
-
src/forward.c:602
Reproducer / Trigger
This can be triggered by sending a DNS query that results in a large local
answer (e.g., a domain configured with many local A records) without EDNS0,
or when specific EDNS0 options are added. The make_local_answer function
will continue adding records until it hits the inflated (and invalid)
limit, overflowing the heap. Add 200 records to the local configuration,
for example:
address=/overflow.test/10.0.0.1
address=/overflow.test/10.0.0.2
..
address=/overflow.test/10.0.0.200
Evidence (AddressSanitizer Output)
=================================================================
==90==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x51d000001d5b at pc 0x65003adc2c1c bp 0x7ffcfd8dfbc0 sp 0x7ffcfd8dfbb0
WRITE of size 4 at 0x51d000001d5b thread T0
#0 0x65003adc2c1b in memcpy
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#1 0x65003adc2c1b in add_resource_record
/root/dnsmasq/src/rfc1035.c:1499
#2 0x65003ae6debd in make_local_answer
/root/dnsmasq/src/domain-match.c:446
#3 0x65003adefb51 in forward_query /root/dnsmasq/src/forward.c:592
#4 0x65003adf2c69 in receive_query /root/dnsmasq/src/forward.c:2013
#5 0x65003ae00b26 in check_dns_listeners
/root/dnsmasq/src/dnsmasq.c:1996
#6 0x65003ae0784d in main /root/dnsmasq/src/dnsmasq.c:1318
#7 0x7290579acd8f in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58
#8 0x7290579ace3f in __libc_start_main_impl ../csu/libc-start.c:392
#9 0x65003adb15e4 in _start (/root/dnsmasq/dnsmasq_asan+0x2c5e4)
0x51d000001d5b is located 0 bytes to the right of 2267-byte region
[0x51d000001480,0x51d000001d5b)
allocated by thread T0 here:
#0 0x729057c60a57 in __interceptor_calloc
../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x65003adc938d in safe_malloc /root/dnsmasq/src/util.c:321
#2 0x65003ae02ac5 in main /root/dnsmasq/src/dnsmasq.c:129
#3 0x7290579acd8f in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29 in memcpy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20260323/589a68d2/attachment-0001.htm>
More information about the Dnsmasq-discuss
mailing list