Skip to content

Use-after-free in c-ares can crash Envoy via compromised or malfunctioning DNS

Moderate
phlax published GHSA-fg9g-pvc4-776f Dec 9, 2025

Package

c-ares (envoy)

Affected versions

<= 1.36.3

Patched versions

1.36.4,1.35.8,1.34.12,1.33.14

Description

Summary

A heap use-after-free vulnerability has been identified in c-ares (<1.34.6). For more information see CVE-2025-62408. The issue occurs during the ares_getaddrinfo query lifecycle when processing a specific sequence of DNS responses. If a trusted adjacent DNS resolver returns an NXDOMAIN response followed by a connection refusal during a search domain retry, it triggers a memory corruption error. This vulnerability can be exploited by an attacker controlling the local DNS infrastructure to cause a Denial of Service (DoS) in Envoy or any application linked against affected versions of c-ares.

Details

The vulnerability is triggered when ares_getaddrinfo processes a non-FQDN query that follows a specific transaction sequence:

  1. Initial Query: A query is sent for a non-FQDN (e.g. www.google.com).
  2. Trigger Response: The upstream DNS server replies with NXDOMAIN.
  3. Search Domain Retry: c-ares attempts to retry the query by appending a search domain.
  4. Connection Failure: The retry attempt fails with a local or network error (e.g., ECONNREFUSED).
  5. Requeue: c-ares requeues the query and resends it immediately.
  6. Use-After-Free: If the resent query succeeds, the function end_query() is called. This invalidates the server connection while it is still being referenced in the call stack by read_answers(), resulting in a heap use-after-free.

This behavior is reproducible in c-ares main (ee2a1c3e) and c-ares release 1.34.5 (d3a507e9).

Relevant source code:

  • ares_process.cread_answers() / process_answer()end_query()

PoC

The following test case demonstrates the underlying memory corruption mechanics. It simulates the specific network topology and response sequence required to trigger the use-after-free condition.

Note: This PoC uses a mock server to deterministically replicate the crash state (NXDOMAIN followed by connection refusal). In a real-world scenario, this sequence would need to be triggered by a compromised or malfunctioning adjacent DNS resolver manipulating the response stream, limiting potential exploitability.

Possible scenarios:

  • The operator has configured a compromised DNS resolver.
  • The DNS traffic is being intercepted/manipulated (Man-in-the-Middle).
  • A legitimate provider malfunctions in a very specific way.
TEST_P(MockUDPChannelTestAI, ConnectionRefusedOnSearchDomainRetry) {
  DNSPacket badrsp4;
  badrsp4.set_response().set_aa()
    .add_question(new DNSQuestion("www.google.com", T_A))
    .set_rcode(NXDOMAIN);

  // Simulate trusted resolver returning NXDOMAIN
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    .WillOnce(SetReplyAndFailSend(&server_, &badrsp4));

  DNSPacket goodrsp4;
  goodrsp4.set_response().set_aa()
    .add_question(new DNSQuestion("www.google.com.first.com", T_A))
    .add_answer(new DNSARR("www.google.com.first.com", 0x0100, {0x01,0x02,0x03,0x04}));

  // Simulate subsequent search domain query logic
  EXPECT_CALL(server_, OnRequest("www.google.com.first.com", T_A))
    .WillOnce(SetReply(&server_, &goodrsp4));

  ares_socket_functions sock_funcs = {0};
  sock_funcs.asendv = ares_sendv_fail;
  ares_set_socket_functions(channel_, &sock_funcs, NULL);

  AddrInfoResult result;
  struct ares_addrinfo_hints hints = {0,0,0,0};
  hints.ai_family = AF_INET;
  hints.ai_flags = ARES_AI_NOSORT;
  ares_getaddrinfo(channel_, "www.google.com", NULL, &hints, AddrInfoCallback, &result);
  Process();
}

Mitigation

Update c-ares library >= 1.34.6

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Adjacent
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

CVE ID

CVE-2025-67514

Weaknesses

Use After Free

The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory belongs to the code that operates on the new pointer. Learn more on MITRE.

Credits