Hi everyone!

I've been using dnsmasq 2.86 as a libvirt resolver on my laptop. 
Sometimes, likely when VM had sent a query during network reconnects, 
dnsmasq had crashed with SIGSEGV.
Rebuilding with ASAN and a few config changes helped me to identify 
likely cause in use-after-free. The full trace is attached in 
asan-trace.txt.

Since patching it I had no crashes (for a few months now). I believe, 
this bug still can be triggered in master branch, so you may find this 
patch useful.

Patch is created against v2.87test8-2-g8e59220

-- 
Best regards, Dmitry
==2011926==ERROR: AddressSanitizer: heap-use-after-free on address 
0x60f0000007c0 at pc 0x565255960fc7 bp 0x7ffe78020960 sp 0x7ffe78020950
READ of size 2 at 0x60f0000007c0 thread T0
    #0 0x565255960fc6 in order 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/domain-match.c:477
    #1 0x565255960fc6 in lookup_domain 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/domain-match.c:143
    #2 0x5652558daefa in forward_query 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/forward.c:258
    #3 0x5652558ddef9 in receive_query 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/forward.c:1636
    #4 0x5652558ed24d in check_dns_listeners 
/usr/src/debug/dnsmasq-2.86/src/dnsmasq.c:1824
    #5 0x56525589ccc9 in main /usr/src/debug/dnsmasq-2.86/src/dnsmasq.c:1251
    #6 0x7fb55d267b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #7 0x56525589f91d in _start (/usr/bin/dnsmasq_bin+0x2e91d)

0x60f0000007c0 is located 0 bytes inside of 168-byte region 
[0x60f0000007c0,0x60f000000868)
freed by thread T0 here:
    #0 0x7fb55d6acf19 in __interceptor_free 
/build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x565255961ebf in cleanup_servers 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/domain-match.c:567

previously allocated by thread T0 here:
    #0 0x7fb55d6ad459 in __interceptor_calloc 
/build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x5652558b630b in whine_malloc 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/util.c:311

SUMMARY: AddressSanitizer: heap-use-after-free 
/home/dvalter/src/archlinux/dnsmasq/trunk/src/dnsmasq-2.86/src/domain-match.c:477
 in order
Shadow bytes around the buggy address:
  0x0c1e7fff80a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1e7fff80b0: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd
  0x0c1e7fff80c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c1e7fff80d0: fd fa fa fa fa fa fa fa fa fa fd fd fd fd fd fd
  0x0c1e7fff80e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
=>0x0c1e7fff80f0: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
  0x0c1e7fff8100: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x0c1e7fff8110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1e7fff8120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1e7fff8130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1e7fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2011926==ABORTING
commit 8e59220480e4bbf6fabb2419619d2e1ece85ef9a
Author: Dmitry Valter <dval...@protonmail.com>
Date:   Mon Feb 21 22:54:17 2022 +0000

    Fix use-after-free after cleanup_servers
    
    Reset serverarraysz to 0 in cleanup_servers to avoid
    use-after-free during lookups. This could cause crashes
    in case upstream resolvers are gone.

diff --git a/src/domain-match.c b/src/domain-match.c
index 3ec49b8..0dc17f1 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -598,6 +598,7 @@ void cleanup_servers(void)
 	  daemon->servers_tail = serv;
 	}
     }
+  daemon->serverarraysz = 0;
 }
 
 int add_update_server(int flags,
_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to