Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault on specific domains with DNSSEC validation #33

Open
smeinecke opened this issue Mar 22, 2018 · 4 comments
Open

Segfault on specific domains with DNSSEC validation #33

smeinecke opened this issue Mar 22, 2018 · 4 comments

Comments

@smeinecke
Copy link

I've tested it multiple times with multiple versions of the getdns library and the getdns-node module and node (v6, v8 and v9) and it seems as if I send a request with enabled DNSSEC validation for specific domains I get the following segmentation fault and the whole node process dies.

My local resolver is unbound 1.6.7

const getdns = require('getdns');
var ctx = getdns.createContext({
        // Upstream recursive servers.
        upstreams : [ '127.0.0.1', ],
        // Request timeout time in milliseconds.
        timeout : 5000,
        // Always return DNSSEC status.
        return_dnssec_status : true
    });

var extensions = {
    // NOTE: enforce DNSSEC security validation and return only secure replies.
    dnssec_return_only_secure: true,
};

var domains = [ 'nic.menu', 'nic.uno', 'nic.onl', 'nic.buzz', 'nic.pink', 'nic.build', 'nic.rich', 'nic.red', 'nic.luxury', 'nic.shiksha', 'nic.kim' ],
    i = 0;
ctx.general(domains[i], getdns.RRTYPE_SOA, extensions);

node: ../deps/uv/src/unix/poll.c:120: uv_poll_start: Assertion `!(((handle)->flags & (UV_CLOSING | UV_CLOSED)) != 0)' failed.

with enabled segfault-handler:

PID 3770 received SIGSEGV for address: 0x7f2342e3ed88
/home/daemons/node_modules/segfault-handler/build/Release/segfault-handler.node(+0x1aaa)[0x7f213c651aaa]
/lib/x86_64-linux-gnu/libpthread.so.0(+0xf890)[0x7f2140538890]
node[0x1340739]
node(uv_poll_start+0x6f)[0x13379ff]
/home/daemons/getdns/build/Release/getdns.node(+0xadea)[0x7f213df72dea]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x2e4d9)[0x7f213dd234d9]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x3918c)[0x7f213dd2e18c]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x212ec)[0x7f213dd162ec]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x21aa1)[0x7f213dd16aa1]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x20b89)[0x7f213dd15b89]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x20d60)[0x7f213dd15d60]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x2205a)[0x7f213dd1705a]
/usr/lib/x86_64-linux-gnu/libgetdns.so.6(+0x2ff45)[0x7f213dd24f45]
/home/daemons/getdns/build/Release/getdns.node(+0xaf50)[0x7f213df72f50]
node[0x1340c08]
node(uv_run+0x156)[0x132f6d6]
node(_ZN4node5StartEiPPc+0x580)[0x10abcf0]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f214019fb45]
node[0x7ba78d]

Any idea?

@smeinecke
Copy link
Author

Oh, btw. the getdns commandline tool works fine:

# getdns_query +dnssec_return_status -a nic.menu SOA
{
  "answer_type": GETDNS_NAMETYPE_DNS,
  "canonical_name": <bindata for nic.menu.>,
  "replies_full":
  [
     <bindata of 0x000081a00001000200000001036e6963...>
  ],
  "replies_tree":
  [
    {
      "additional":
      [
        {
          "do": 1,
          "extended_rcode": 0,
          "rdata":
          {
            "rdata_raw": <bindata of 0x>
          },
          "type": GETDNS_RRTYPE_OPT,
          "udp_payload_size": 65535,
          "version": 0,
          "z": 0
        }
      ],
      "answer":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for nic.menu.>,
          "rdata":
          {
            "expire": 1814400,
            "minimum": 1800,
            "mname": <bindata for a.nic.menu.>,
            "rdata_raw": <bindata of 0x0161c00c07737570706f72740b617269...>,
            "refresh": 1800,
            "retry": 300,
            "rname": <bindata for support.ariservices.com.>,
            "serial": 1518897626
          },
          "ttl": 900,
          "type": GETDNS_RRTYPE_SOA
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for nic.menu.>,
          "rdata":
          {
            "algorithm": 8,
            "key_tag": 64353,
            "labels": 2,
            "original_ttl": 900,
            "rdata_raw": <bindata of 0x00060802000003845ad7b9805ab01e70...>,
            "signature": <bindata of 0x463819766cb4943f4a665411caf8601b...>,
            "signature_expiration": 1524087168,
            "signature_inception": 1521491568,
            "signers_name": <bindata for nic.menu.>,
            "type_covered": GETDNS_RRTYPE_SOA
          },
          "ttl": 900,
          "type": GETDNS_RRTYPE_RRSIG
        }
      ],
      "answer_type": GETDNS_NAMETYPE_DNS,
      "authority": [],
      "canonical_name": <bindata for nic.menu.>,
      "dnssec_status": GETDNS_DNSSEC_SECURE,
      "header":
      {
        "aa": 0,
        "ad": 1,
        "ancount": 2,
        "arcount": 1,
        "cd": 0,
        "id": 0,
        "nscount": 0,
        "opcode": GETDNS_OPCODE_QUERY,
        "qdcount": 1,
        "qr": 1,
        "ra": 1,
        "rcode": GETDNS_RCODE_NOERROR,
        "rd": 1,
        "tc": 0,
        "z": 0
      },
      "question":
      {
        "qclass": GETDNS_RRCLASS_IN,
        "qname": <bindata for nic.menu.>,
        "qtype": GETDNS_RRTYPE_SOA
      }
    }
  ],
  "status": GETDNS_RESPSTATUS_GOOD
}

@smeinecke
Copy link
Author

Does anyone have the same problem and could confirm this issue?

@joelpurra
Copy link
Collaborator

@smeinecke: thanks for the report and test code! I can confirm the problem, but see below for configuration details.

  • Which version of getdns do you have installed on your machine?
  • Do you see the same problem (if possible to test) in unbound v1.7.0?

I sometimes get segfaults from unbound, but haven't had enough time to dig deep enough. @wcawijngaards tried to explain what I was looking at in the weekly getdns developer's hangouts meeting once (or twice) but it's not a level of programming I'm fast/comfortable debugging.

My setup:

Recursive mode

Note that you are running in default recursive mode, as resolution_type: getdns.RESOLUTION_STUB was not set in the context; your upstreams should be ignored. (See also getdns_query below.)

// NOTE: need a callback to run test code.
const loggingCallback = (...args) => { console.log(...args); };

// NOTE: added callback to single test lookup.
ctx.general(domains[i], getdns.RRTYPE_SOA, extensions, loggingCallback);

// NOTE: looping over all example domains also works.
domains.forEach((domain) => ctx.general(domain, getdns.RRTYPE_SOA, extensions, loggingCallback));

Your test code seems to work for me in recursive mode, after adding a simple lookup result callback.

  • Did you test locally in recursive or stub mode?
  • Was the result the same, or different?

Note that the results should contain status GETDNS_RESPSTATUS_GOOD (900) and per-answer dnssec_status GETDNS_DNSSEC_SECURE (400).

Stub mode

{
// NOTE: added option for stub resolver context, deferring lookups to the upstream recursive servers.
resolution_type: getdns.RESOLUTION_STUB,
upstreams: ...
}

The test code segfaults in stub mode. Testing with other domains (joelpurra.se, getdnsapi.net) surprisingly works well.

  • What is different about your provided test domains?
    • Something in the DNS reply in general?
    • Something with DNSSEC?

getdns_query

Note that you are running getdns_query in recursive mode as well. Try this:

# NOTE: use local dns server in stub mode.
getdns_query @127.0.0.1 +dnssec_return_status -s -a nic.menu SOA

unbound

Even if getdns_query works, can you confirm that your local unbound resolver is correctly set up to handle DNSSEC lookups? I've forgotten to do that before.

# NOTE: check that "flags" include "ad".
dig @127.0.0.1 com. SOA +adflag

@NodePing
Copy link

NodePing commented Aug 9, 2019

Just getting started with getdns and I'm seeing the same thing. Only with DNSSEC enabled queries and only about 1/4 of the time do they segfault. I'm doing a query for A records.

I'm using remote resolvers (authoritative ones). I've tried several different ones and it doesn't seem to make a difference what the resolvers are.

When it segfaults the runtime is about 1/10 of a regular query (22ms vs 250ms) so I think it's dorking out before a response is received.

I hope that helps and you're able to track down the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants