[Dnsmasq-discuss] rr_on_list stuck in infinite loop, dnsmasq unresponsive

Simon Kelley simon at thekelleys.org.uk
Mon Feb 19 23:33:22 UTC 2024


https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=89aad014685161318318737dc0e350ee4dae982d

should fix this.


Simon.

On 19/02/2024 23:16, Simon Kelley wrote:
> 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 at lists.thekelleys.org.uk
>> https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss




More information about the Dnsmasq-discuss mailing list