CVE-2020-22217: c-ares SOA Parser Buffer Overflow Patch and Risk

  • Thread Author
A heap buffer overflow in the c-ares DNS parsing code — tracked as CVE-2020-22217 — lets a malicious name server craft an SOA reply that can crash or destabilize applications that use the vulnerable library, and in some configurations could lead to remote code execution. The bug was found in the function ares_parse_soa_reply (file ares_parse_soa_reply.c), was fixed upstream in the c-ares tree, and has been patched in major distributions; however, the discovery, scoring discrepancies, and the library’s presence inside widely used projects make this more than a routine maintenance item for application maintainers and system administrators.

Hacker analyzes the CVE-2020-22217 vulnerability with a magnifying glass beside a stack of colorful cubes.Background / Overview​

c-ares is a compact, widely used C library for asynchronous DNS resolution. It is embedded directly or optionally linked by many networked applications and runtimes (for example: libcurl can be built to use c-ares, Node.js has historically bundled or depended on c-ares for asynchronous DNS functions, and other projects like Wireshark and language runtimes have integrated it). Because c-ares parses DNS responses from remote servers, parsing bugs are high-value targets: a malformed DNS answer from a hostile nameserver can trigger crashes or memory corruption in any application that trusts that DNS response.
The specific vulnerability, CVE-2020-22217, was identified as a buffer overflow (a heap-read/over-read leading to potential overflow conditions) in the SOA parsing path. The public vulnerability records list the affected ranges as “c-ares before 1_16_1 through 1_17_0,” and upstream fixes were merged into the c-ares repository. Distributors and downstream packages (Debian, Ubuntu, Oracle Linux, and other vendors) have issued updates to non-vulnerable versions.

What changed technically: the root cause and fix​

How the parser failed​

At the center of CVE-2020-22217 is the code that decodes the fields of a DNS SOA (Start of Authority) resource record. Parsing SOA records requires reading variable-length fields (names and several fixed-size integers and text fields). The vulnerable code path did not sufficiently check that the input buffer length covered the expected structure before copying or advancing pointers to parse subsequent fields. In short, a crafted SOA reply could trick the parser into doing out-of-bounds reads/writes by making it believe a name or field was shorter than it actually was. The result is heap memory corruption or an invalid read that leads to a crash — a classical parsing-overflow scenario. (github.com)

The upstream patch​

The c-ares maintainers accepted a small, targeted change that adds explicit bounds checking before the code advances past the expanded domain name and before copying the header-size data. The GitHub commit that fixed the issue makes a defensive check: it ensures the remaining buffer length is at least the length of the name plus the header fixed-size field before proceeding. That single extra check prevents the parsing routine from attempting to read or copy memory past the end of the DNS response buffer. The change is minimal but effective and was incorporated into the releases noted in the changelog. (github.com)

Affected versions, timelines, and vendor responses​

  • The canonical CVE entry and NVD description state the vulnerable range as “before 1_16_1 thru 1_17_0.” That language has caused some confusion in downstream packaging — the practical takeaway is: upgrade to a fixed version distributed by your OS vendor (or to a c-ares version later than the release that includes the fix).
  • Upstream c-ares incorporated the fix in the commit referenced above; the changelog entry for c-ares 1.17.0 documents “avoid read-heap-buffer-overflow in ares_parse_soa_reply found during fuzzing” as a security fix. Packagers (Debian, Ubuntu, Oracle Linux and others) subsequently released patched packages for their supported distributions. (github.com)
  • Major distributions issued advisories and backports. Debian published a security update and tracked fixed package versions; Ubuntu enumerated the vulnerability and assigned a medium priority with a CVSS 3.x base score of 5.9, while some vendors and scanners (notably one cloud vendor advisory) have reported higher severity values — more on scoring differences below. Administrators should treat vendor-supplied packages as authoritative for their environment and apply the recommended updates.

Exploitability and impact: DoS vs. RCE, real-world risk​

Two different impact vectors matter in practice: Denial of Service (DoS) and Remote Code Execution (RCE).
  • Denial of Service: The vulnerability reliably allows an attacker who can return a specially crafted DNS reply to crash the resolver instance (and therefore the host process). That translates to application-level unavailability — an easy, high-impact outcome when a network service or client depends on the process that includes c-ares. In many installations, repeated malicious replies will sustain the outage. Multiple advisories list Availability as the primary impact.
  • Remote Code Execution: In some buffer-overflow cases, carefully crafted inputs can convert memory corruption into code execution. Public records for CVE-2020-22217 emphasize the overflow/heap read and list DoS as the clear impact; some vendors and analysts caution that RCE cannot be ruled out depending on the allocator, ASLR, compiler hardening and the victim process’ memory layout. Several distributors describe the flaw as enabling denial-of-service; at least one third-party database (Amazon’s ALAS) lists a very high CVSS score (9.8), which suggests a more severe RCE-level concern in some scoring contexts. This disagreement largely stems from different assumptions about whether memory corruption could be escalated to code execution, and what protections (DEP, ASLR, stack canaries, hardened allocators) are present in the target environment.
In practical terms: if you embed or link c-ares into a persistent network-facing process that parses untrusted responses, assume high impact until you’ve patched and validated the build. For short-lived client utilities that use system resolvers with full OS-level hardening, the immediate RCE risk may be lower, but the DoS vector remains real. The industry’s common guidance is conservative: fix quickly.

Why this matters: the c-ares ecosystem​

c-ares plays a subtle but central role in many modern stacks:
  • libcurl can be compiled with c-ares to perform non-blocking DNS lookups; widespread builds of libcurl (used in command-line tools, system agents and embedded appliances) may therefore be indirectly affected if they use a vulnerable c-ares.
  • Node.js historically bundles or depends on c-ares for its asynchronous DNS functions (the DNS module uses c-ares for many operations). A vulnerable c-ares inside a language runtime increases the blast radius: every application running on that runtime inherits the parsing library’s risk.
  • Other ecosystem projects and language bindings (some npm modules, language runtimes, and networking libraries) may either link system c-ares or include it directly. That means the vulnerability can cross application and packaging boundaries and requires coordination: update libraries; rebuild dependent binaries; push updated packages to device fleets.
This transitive exposure is why canonical exploitation scenarios involve an attacker controlling a nameserver or otherwise convincing the victim to query a malicious name: such interactions are relatively easy to set up in many testing or hostile-network contexts. The vulnerability was discovered by fuzzing — a sign that automated testing can find dangerous parser edge cases, but also that many code paths are subtle and critical.

Detection and mitigation strategies​

Short-term, medium-term, and long-term steps for defenders:
  • Immediate (apply patches)
  • Inventory: identify all systems and packages that include c-ares — check system packages (libc-ares packages, libcares-dev, etc.), bundled copies inside application distributions, and language runtime installations. Focus on network-facing daemons, long-running services, and language runtimes that bundle native dependencies.
  • Patch: upgrade to the vendor-provided fixed package or to a c-ares version that includes the fix (the upstream fix is in the commits merged into the 1.17.0/1.17.1 work stream; distributors have backported fixes). Use your OS vendor advisories to choose the correct package version. (github.com)
  • Rebuild: if your product bundles c-ares (static link), rebuild with the patched c-ares and redeploy. Do not assume system updates will fix statically linked libraries inside third-party binaries.
  • Short- to medium-term mitigations if immediate patching is difficult
  • Run vulnerable processes with least privilege, appropriate sandboxes and resource limits to reduce blast radius.
  • Isolate systems that perform external DNS queries to untrusted servers; where feasible, restrict which upstream resolvers are queried.
  • Rate-limit or drop unusual DNS responses at network boundaries (e.g., restrict which name servers hosts may talk to, monitor for anomalous SOA records).
  • Monitor for process crashes and abnormal restarts that may indicate exploitation attempts. Logging resonant crash stack traces that point into c-ares parsing code is a high-value detection signal.
  • Detection (log and network indicators)
  • Look for repeated crashes or segmentation faults in processes linked to c-ares.
  • Track DNS responses with unusually long or malformed SOA records in network captures.
  • Use service instrumentation (core dumps, ASAN or UBSAN in testing builds) to triage suspicious inputs and create signatures for IDS/IPS. Note that exploitation may require a crafted response and a vulnerable client to initiate the query. (github.com)

Remediation checklist (practical, prioritized)​

  • Identify all installs that use c-ares:
  • System packages: check package manager (apt, rpm, etc.) for libc-ares or c-ares.
  • Embedded/bundled: vendor packages and third-party applications may include their own c-ares copy; inspect application trees and binary ldd outputs.
  • Apply vendor patches:
  • Use your distribution’s security updates (Debian’s DLA, Ubuntu USN and vendor advisories) rather than ad-hoc upstream tarballs unless you manage your own builds.
  • Rebuild and redeploy:
  • For static-linked or bundled c-ares, rebuild the full product with a patched c-ares release (or the patched upstream commit). Confirm the binary was rebuilt by checking the symbol table or build logs.
  • Validate:
  • Re-run targeted tests against patched builds, including fuzzing and malformed SOA responses, to verify that the specific parsing path no longer triggers crashes. The upstream fix was itself discovered through fuzzing; follow a similar testing discipline. (github.com)
  • Monitor:
  • Add watch rules for crashes, core dumps and unusual DNS reply patterns; implement alerting to detect post-patch regressions or rollback scenarios.

Why scores and advisories sometimes disagree​

When reviewing CVE records you may see different severity numbers. For CVE-2020-22217, NVD and multiple Linux vendors list CVSS 3.x ≈ 5.9 (medium) with the principal impact labeled as Availability (DoS). At the same time, some cloud/third-party trackers list higher scores (even up to 9.8) under assumptions that memory corruption may be leveraged into code execution in some environments. The discrepancy stems from the different assumptions made when scoring:
  • CVSS base score depends on whether analysts assume only a crash (DoS) or plausible RCE; it also depends on attack complexity, required privileges and availability of user interaction.
  • Distributors that know their build chains and mitigations (e.g., whether the target package is compiled with hardened allocators, PIE, or other mitigations) may assign a more conservative (lower) severity if RCE is judged unlikely in their packaged environment.
  • Independent scanners or cloud providers sometimes use worst-case assumptions in automated severity mapping, which can overstate impact for environments with minimal hardening.
The operational guidance is straightforward: don’t rely on a single numeric rating. Treat the library as high-priority if it’s embedded in long-running or network-exposed processes, and apply vendor-provided updates.

Strengths, weaknesses, and future risk — critical analysis​

What went right​

  • The bug was found by fuzzing — demonstrating the value of automated testing for parser code in network libraries.
  • The upstream project responded quickly with a small, targeted patch that preve access.
  • Distributors and vendors produced timely advisories and backports for major Linux distributions so admins could apply vendor-approved fixes. (github.com)

What remains concerning​

  • The library is embedded widely and sometimes statically linked; you cannot fix a system simply by updating the OS if binaries include their own c-ares copy. That increases the maintenance burden for vendors and integrators.
  • Parser flaws in DNS code are inherently high-risk because attackers only need to control a DNS response path; in some deployments, the attacker can easily set up a malicious nameserver or trick an application to resolve a hostile name. That makes exploitation scenarios realistic on open networks or controlled test environments.
  • Score variance across sources can cause triage paralysis. Administrators should prioritize based on exposure and whether the vulnerable library is used in network-facing or high-privilege contexts.

Recommendations (for different audiences)​

  • For system administrators
  • Apply vendor-supplied c-ares updates immediately to servers and endpoints that use system packages.
  • Identify and prioritize long-running, network-facing services that link to c-ares (e.g., proxies, agents, runtimes). Rebuild and redeploy if the application bundles c-ares.
  • For application maintainers and product vendors
  • If you statically link c-ares, update the bundled library and rebuild release artifacts; do not assume system updates will cover your static components.
  • Add parser fuzzing to your CI pipeline (the vulnerability itself was discovered by fuzzing). Treat parser code as a high-risk attack surface and invest in hardening and test coverage. (github.com)
  • For security teams and incident responders
  • Prioritize telemetry for process crashes and unexpected restarts of services that use c-ares.
  • Review network logs and DNS telemetry for anomalous SOA replies and suspicious DNS servers being queried by hosts. Implement egress controls where appropriate.

Conclusion​

CVE-2020-22217 is a textbook example of how a small parsing bug in a low-level network library can ripple into significant operational risk. The defect was discovered by fuzzing, patched in a compact upstream change, and backported by distributions — but the real challenge was and remains distribution and integration: c-ares is embedded in popular projects and may be linked statically, so the fix requires action across multiple layers (OS packages, application builds, runtime images).
The practical advice is immediate and straightforward: inventory, patch, rebuild where necessary, and harden monitoring. Parser hardening and fuzzing must be part of the development lifecycle going forward; the community response to this issue shows the value of that discipline. Treat DNS parsing vulnerabilities as high-priority until you can confirm the vulnerable code is removed or the process is rebuilt with the fixed library. (github.com)

Source: MSRC Security Update Guide - Microsoft Security Response Center
 

Back
Top