<div dir="ltr"><p>Dear Simon and the dnsmasq community,</p><p>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).</p><h3>Summary</h3><p>The issue lies in <code>src/forward.c</code> where the packet boundary limit pointer is calculated. The code incorrectly uses pointer arithmetic on <code>struct dns_header *</code> instead of casting to <code>unsigned char *</code> first. Since <code>sizeof(struct dns_header)</code> is 12 bytes, the limit pointer is inflated by a factor of 12, allowing <code>add_resource_record()</code> to write far beyond the allocated heap buffer.</p><h3>Details & Root Cause</h3><p>In <code>src/forward.c</code>, several lines calculate the buffer limit as follows:
<code>(unsigned char *)(header + daemon->edns_pktsz)</code> or <code>(char *)(header + replylimit)</code></p><p>Because <code>header</code> is of type <code>struct dns_header *</code>, C pointer logic scales the addition.</p><ul><li><p><b>Intended:</b> <code>header + 512 bytes</code></p></li><li><p><b>Actual:</b> <code>header + (512 * 12) = header + 6144 bytes</code></p></li></ul><p>However, the buffer <code>daemon->packet</code> is typically allocated around <b>1547 - 2267 bytes</b>.</p><h3>Impacted Lines (Current Master)</h3><ul><li><p><code>src/forward.c:517</code></p></li><li><p><code>src/forward.c:592</code></p></li><li><p><code>src/forward.c:600</code></p></li><li><p><code>src/forward.c:602</code></p></li></ul><h3>Reproducer / Trigger</h3><p>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 <code>make_local_answer</code> 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:</p><p>address=/overflow.test/<a href="http://10.0.0.1">10.0.0.1</a><br>address=/overflow.test/<a href="http://10.0.0.2">10.0.0.2</a><br>..<br>address=/overflow.test/<a href="http://10.0.0.200">10.0.0.200</a></p><h3>Evidence (AddressSanitizer Output)</h3><span class="gmail-"><span class="gmail-ng-tns-c2858875814-228 gmail-ng-star-inserted"><div class="gmail-code-block gmail-ng-tns-c2858875814-228 gmail-ng-animate-disabled gmail-ng-trigger gmail-ng-trigger-codeBlockRevealAnimation"><div class="gmail-code-block-decoration gmail-header-formatted gmail-gds-title-s gmail-ng-tns-c2858875814-228 gmail-ng-star-inserted">=================================================================<br>==90==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x51d000001d5b at pc 0x65003adc2c1c bp 0x7ffcfd8dfbc0 sp 0x7ffcfd8dfbb0<br>WRITE of size 4 at 0x51d000001d5b thread T0<br>    #0 0x65003adc2c1b in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29<br>    #1 0x65003adc2c1b in add_resource_record /root/dnsmasq/src/rfc1035.c:1499<br>    #2 0x65003ae6debd in make_local_answer /root/dnsmasq/src/domain-match.c:446<br>    #3 0x65003adefb51 in forward_query /root/dnsmasq/src/forward.c:592<br>    #4 0x65003adf2c69 in receive_query /root/dnsmasq/src/forward.c:2013<br>    #5 0x65003ae00b26 in check_dns_listeners /root/dnsmasq/src/dnsmasq.c:1996<br>    #6 0x65003ae0784d in main /root/dnsmasq/src/dnsmasq.c:1318<br>    #7 0x7290579acd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58<br>    #8 0x7290579ace3f in __libc_start_main_impl ../csu/libc-start.c:392<br>    #9 0x65003adb15e4 in _start (/root/dnsmasq/dnsmasq_asan+0x2c5e4)<br><br>0x51d000001d5b is located 0 bytes to the right of 2267-byte region [0x51d000001480,0x51d000001d5b)<br>allocated by thread T0 here:<br>    #0 0x729057c60a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154<br>    #1 0x65003adc938d in safe_malloc /root/dnsmasq/src/util.c:321<br>    #2 0x65003ae02ac5 in main /root/dnsmasq/src/dnsmasq.c:129<br>    #3 0x7290579acd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58<br><br>SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29 in memcpy</div></div></span></span></div>