Skip to main content
← All libraries
Network · C

How to fuzz c-ares

Node.js and curl use c-ares for DNS — a crafted DNS response can corrupt the heap.

c-ares is the asynchronous DNS resolver used by Node.js, curl, and many network daemons. Its DNS message parser follows label compression pointers and assembles resource record data with length fields sourced entirely from the network, making it a prime target for heap overflows via malformed DNS responses.

Common bug classes

  • Heap buffer overflow in DNS label decompression pointer loop
  • Integer overflow in RDATA length accumulation across RRs
  • Out-of-bounds read in SRV/MX record priority/weight parsing
  • Infinite loop via circular label compression pointer chain
  • Null dereference on zero-length QNAME in query response

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <ares.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  ares_channel channel;
  struct ares_options opts = {};
  if (ares_init_options(&channel, &opts, 0) != ARES_SUCCESS) return 0;
  /* Feed crafted DNS response directly to the parser */
  ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
  /* Parse DNS reply buffer directly */
  struct hostent *host = NULL;
  int naddrs = 0;
  ares_parse_a_reply((const unsigned char *)data, (int)size, &host, NULL, &naddrs);
  if (host) ares_free_hostent(host);
  ares_destroy(channel);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Notable CVEs found by fuzzing

  • CVE-2023-31130
  • CVE-2023-32067
Start fuzzing c-ares on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.