Wow, excellent bug report, thank you.

Took me straight to the stupid error.

src/dbus.c around line 834. The code block controlled by "if (!done)" should include the line "done = 1;" Same thing below for filter AAAA.

I'll push the patch directly.

Cheers,

Simon.


On 19/02/2024 21:29, Clayton Craft wrote:
It seems like sometimes the rrlist given to rr_on_list can be a circular linked
list:

     0x0000aaaabbf57044 in rr_on_list (list=0xaaaabbfe1990 <list>, rr=5) at 
util.c:120
     120       while (list)
     (gdb) p list
     $1 = (struct rrlist *) 0xaaaabbfe1990 <list>
     (gdb) p list.next
     $3 = (struct rrlist *) 0xaaaabbfe1980 <list>
     (gdb) p list.next.next
     $4 = (struct rrlist *) 0xaaaabbfe1990 <list>

This causes rr_on_list to get stuck in an infinite loop, and dnsmasq to consume
100% CPU and be completely unresponsive. I generated a flamegraph of dnsmasq and
found that it was stuck here, then attached gdb to confirm.

The conditions to trigger this aren't well understood by me... it seems to
happen when we use dnsmasq's dbus interface to toggle filtering ("set_filter A
bool"). But I've had trouble reproducing it manually. We hit it a lot when using
a NetworkManager dispatcher script to apply filtering in dnsmasq conditionally.

The issue does *not* go away when I revert 3de7289.

If rrlist is a circular list, then rr_on_list should have an escape if head was
already visited or ? I don't understand the dnsmasq code enough to have any real
suggestions for how to proceed with fixing this :)

Full bt:

(gdb) bt full
#0  0x0000aaaad9077028 in rr_on_list (
     list=0xaaaad9101990 <list>, rr=5) at util.c:120
No locals.
#1  0x0000aaaad90cd718 in rrfilter (header=0xffffa56e3580,
     plen=0xfffff663bc80, mode=2) at rrfilter.c:233
         pstart = 0xffffa56e35ac "\300\f"
         type = 5
         class = 1
         rrs = 0xffffa5566b40
         rr_sz = 12
         p = 0xffffa56e35c0 "\3008"
         rr_found = 0
         i = 0
         rdlen = 8
         qtype = 28
         qclass = 1
         chop_an = 0
         chop_ns = 0
         chop_ar = 0
#2  0x0000aaaad9089c40 in process_reply (
     header=0xffffa56e3580, now=1708377610,
     cache_secure=0, bogusanswer=0, ad_reqd=0, do_bit=0, added_pheader=0, 
query_source=0xffffa56d1240,
     limit=0xffffa56e3a50 "", ede=-1) at forward.c:848
         pheader = 0x0
         sizep = 0x0
         ipsets = 0x0
         nftsets = 0x0
         is_sign = 0
         rcode = 0
         plen = 281473457238616
#3  0x0000aaaad908b68c in return_reply (now=1708377610, forward=0xffffa56d1240, 
header=0xffffa56e3580, n=92, status=524288)
     at forward.c:1382
         check_rebind = 0
         no_cache_dnssec = 0
         cache_secure = 0
         bogusanswer = 0
         nn = 187650762387748
         ede = -1
#4  0x0000aaaad908b21c in reply_query (fd=10, now=1708377610) at forward.c:1301
         header = 0xffffa56e3580
         serveraddr = {sa = {sa_family = 2, sa_data = 
"\0005\300\000\000\001\000\000\000\000\000\000\000"}, in = {
             sin_family = 2, sin_port = 13568, sin_addr = {s_addr = 16777408}, sin_zero = 
"\000\000\000\000\000\000\000"},
           in6 = {sin6_family = 2, sin6_port = 13568, sin6_flowinfo = 16777408, 
sin6_addr = {__in6_union = {
                 __s6_addr = 
"\000\000\000\000\000\000\000\000\224\202\t٪\252\000", __s6_addr16 = {0, 0, 0, 
0, 33428, 55561,
                   43690, 0}, __s6_addr32 = {0, 0, 3641279124, 43690}}}, 
sin6_scope_id = 0}}
         forward = 0xffffa56d1240
         addrlen = 16
         n = 92
         server = 0xffffa5566e70
         hash = 0xffffa55059b0
         first = 32
         last = 33
         c = 32
#5  0x0000aaaad90982c4 in check_dns_listeners (now=1708377610) at dnsmasq.c:1831
         serverfdp = 0x0
         listener = 0xe0af57cb29b80071
         rfl = 0xfffff663bf80
         i = 0
         pipefd = {-653704516, 43690}
#6  0x0000aaaad9096c84 in main (argc=12, argv=0xfffff663c1d8) at dnsmasq.c:1269
         timeout = -1
         now = 1708377610
         sigact = {__sa_handler = {sa_handler = 0x1, sa_sigaction = 0x1}, 
sa_mask = {__bits = {0, 187651085026544,
               281473457229824, 281474815476000, 281473456612332, 
187651085026504, 281473457229824, 281474815476032,
               281473456612716, 187651085026504, 281473457238016, 
281474815476096, 281473456885404, 281473457238016,
               281474815476184, 224}}, sa_flags = 0, sa_restorer = 0xffffa56eb000 
<env_alloced_n>}
         if_tmp = 0x0
         piperead = 7
         pipefd = {7, 8}
         err_pipe = {0, -1}
         ent_pw = 0xffffa56eb4e0 <pw>
         script_uid = 0
         script_gid = 0
         gp = 0xffffa56eb4a0 <gr>
         i = 20
         max_fd = 1024
         baduser = 0x0
         log_err = 0

-Clayton


_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

_______________________________________________
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