Skip to content

CVE-2026-33630: Verified Reproduction

CVE-2026-33630: c-ares CVE-2026-33630 RCE primitive construction from confirmed remote UAF

CVE-2026-33630 is verified against c-ares/c-ares · c. Affected versions: >1.32.3 through 1.34.6. Fixed in 1.34.7. Vulnerability class: RCE. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00263.

REPRO-2026-00263 c-ares/c-ares · c RCE Jul 7, 2026 CVE entry .txt
Severity
HIGH
Confidence
HIGH
Reproduced in
54m 27s
Tool calls
252
Spend
$14.17
01 · Overview

What Is CVE-2026-33630?

CVE-2026-33630 is a high-severity, remotely reachable use-after-free/double-free (CWE-416) in c-ares's query-completion handling, triggerable through the public ares_getaddrinfo() API over TCP DNS. Pruva reproduced it as a vulnerable-only control-flow hijack marker (reproduction REPRO-2026-00263).

02 · Severity & CVSS

CVE-2026-33630 Severity

CVE-2026-33630 is rated high severity.

HIGH threat level
Weakness CWE-416 — Use After Free

High — serious impact or readily exploitable. Prioritize remediation.

03 · Affected Versions

Affected c-ares/c-ares Versions

c-ares/c-ares · c versions >1.32.3 through 1.34.6 are affected.

How to Reproduce CVE-2026-33630

$ pruva-verify REPRO-2026-00263
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00263/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-33630

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

malicious TCP DNS server responses (FORMERR without OPT, duplicate same-qid NXDOMAIN, TCP reset) plus deterministic heap-reclaim payload supplied through c-ares public allocator API to model attacker-controlled reclaimed heap content

Attack chain
  1. ares_getaddrinfo(AF_INET) over TCP
  2. read_answers() deferred ENDQUERY flush
  3. host_callback() reentrant next_lookup/end_hquery after TCP reset
  4. hquery_free()
  5. stale host_callback consumes forged host_query
  6. callback/arg and executes sentinel
Runnable proof: reproduction_steps.sh
Captured evidence: rce reclaim fixed attempt1rce reclaim fixed attempt2
How the agent worked 529 events · 252 tool calls · 54 min
54 minDuration
252Tool calls
103Reasoning steps
529Events
1Dead-ends
Agent activity over 54 min
Support
16
Hypothesis
2
Repro
311
Judge
76
Variant
119
0:0054:27

Root Cause and Exploit Chain for CVE-2026-33630

Versions: reproduced on c-ares v1.34.6 (3ac47ee46edd8ea40370222f91613fc16c434853).Fixed: version/control: c-ares v1.34.7 (d63b7de3a3568d14ab1351374b205365aed51cca), which contains fix commit d823199b688052dcdc1646f2ab4cb8c16b1c644a.

CVE-2026-33630 in c-ares is a remotely reachable use-after-free/double-free in query-completion handling that can be triggered through the public ares_getaddrinfo() API over TCP DNS. In c-ares v1.34.6, deferred ENDQUERY processing invokes a query callback while the query remains linked in the channel lookup tables. A malicious TCP DNS peer can drive a reentrant completion path that frees the associated host_query; subsequent stale use can consume reclaimed attacker-shaped fields. This run demonstrates a vulnerable-only benign control-flow hijack marker: under the real TCP DNS trigger and a deterministic public allocator-hook heap reclaim, v1.34.6 executes a sentinel callback from a forged reclaimed host_query, while v1.34.7 never executes the marker.

  • Package/component affected: c-ares, specifically src/lib/ares_process.c deferred requeue/endquery handling and src/lib/ares_getaddrinfo.c host_query callback completion state.
  • Affected versions: reproduced on c-ares v1.34.6 (3ac47ee46edd8ea40370222f91613fc16c434853).
  • Fixed version/control: c-ares v1.34.7 (d63b7de3a3568d14ab1351374b205365aed51cca), which contains fix commit d823199b688052dcdc1646f2ab4cb8c16b1c644a.
  • Risk level and consequences: high. A malicious DNS/TCP peer can drive the vulnerable completion timing through a real resolver API. This run demonstrates that reclaimed host_query callback fields can be consumed as control flow in the vulnerable build, which is equivalent to a code-execution primitive in-process when heap content is controlled.

Impact Parity

  • Disclosed/claimed maximum impact: code execution/RCE primitive construction from the confirmed remote c-ares UAF/double-free.
  • Reproduced impact from this run: vulnerable-only sentinel function execution (SENTINEL EXECUTION MARKER FIRED) through a forged reclaimed host_query object after a real malicious TCP DNS peer drives ares_getaddrinfo().
  • Parity: full.
  • Not demonstrated: no shell command execution or external payload execution was attempted. The proof uses a benign in-process sentinel callback as the code-execution/control-flow marker, which the ticket explicitly allowed as an acceptable safe proof form.

Root Cause

In v1.34.6, read_answers() accumulates deferred ENDQUERY entries in a requeue array and later flushes them by looking up the query by QID, invoking query->callback(query->arg, ...), and only then freeing/detaching the query with ares_free_query(query). Because the query remains visible in the channel's queries_by_qid/all_queries structures while its callback is running, callback-driven reentrant resolver activity can find and complete/free related state before the outer completion path has finished. For the ares_getaddrinfo() path, host_callback() may call end_hquery()/hquery_free() during this reentrant sequence, then later stale code continues to operate on the freed host_query pointer.

The fixed code introduces centralized ares_flush_requeue() handling and detaches the query before invoking the callback. In the fixed implementation, the ENDQUERY drain performs ares_detach_query(query) before query->callback(...), so reentrant cancellation/completion cannot rediscover and free the same query or drive the stale host_query consumption window. The reproduction anchors the negative control to v1.34.7, which contains fix commit d823199b688052dcdc1646f2ab4cb8c16b1c644a.

Reproduction Steps

  1. Use bundle/repro/reproduction_steps.sh.
  2. The script reuses or clones c-ares into the prepared project cache, checks out v1.34.6 and v1.34.7, verifies that only the fixed checkout contains ares_flush_requeue, builds static non-sanitized libcares.a for both, and compiles bundle/repro/rce_reclaim_harness.c against each build.
  3. The harness calls public ares_getaddrinfo(AF_INET) and sends traffic through a real localhost TCP DNS socket to a malicious peer. The peer sends FORMERR without OPT, a duplicate same-QID NXDOMAIN, observes the follow-on search-domain DNS query, and resets the TCP connection.
  4. The harness uses the public ares_library_init_mem() allocator hooks to deterministically retain and rewrite freed 144-byte host_query chunks with a forged callback/arg/addrinfo layout. Success is counted only when c-ares later consumes the forged callback and fires the sentinel.
  5. The script runs 30 vulnerable attempts and 10 fixed attempts. Expected evidence is at least two vulnerable sentinel executions and zero fixed sentinel executions, with TCP DNS boundary evidence in both builds.

Evidence

Key artifacts:

  • bundle/repro/reproduction_steps.sh — self-contained reproducer.
  • bundle/repro/rce_reclaim_harness.c — C harness using real c-ares public APIs and real TCP DNS peer.
  • bundle/logs/reproduction_steps.log — aggregate build/run/proof log.
  • bundle/logs/rce_reclaim_vuln_attempt*.log — vulnerable attempt logs.
  • bundle/logs/rce_reclaim_fixed_attempt*.log — fixed negative-control logs.
  • bundle/repro/runtime_manifest.json — runtime evidence manifest.
  • bundle/repro/validation_verdict.json — structured verdict.

The latest verified run ended with:

[repro] counts: vuln_boundary_count=30 fixed_boundary_count=10 vuln_forge_count=30 rce_marker_count=4 fixed_marker_count=0
[repro] wrote validation_verdict.json: claim_outcome=confirmed observed_impact_class=code_execution
[repro] proof summary: rce_marker_fired=1 rce_marker_count=4 fixed_marker=0 fixed_marker_count=0 vuln_boundary=1 fixed_boundary=1 controlled_reclaim=1 vuln_runs_ok=1 fixed_runs_ok=1
[repro] SUCCESS: vulnerable-only sentinel code execution marker fired through reclaimed host_query over real TCP DNS path

Representative vulnerable marker evidence:

[server] accepted TCP DNS connection on 127.0.0.1:40863
[server] sending FORMERR without OPT for qid=22298
[server] sending second response with duplicate qid=22298 (NXDOMAIN, no OPT)
[server] observed follow-on search-domain query qid=22298 qtype=1 length=33
[server] resetting TCP connection with SO_LINGER zero
[allocator] FORGED_RECLAIM host_query ptr=0x5588b747d020 callback@24=0x55888b4cbcf9 arg@32=0x7ffeddcb4bc8 ai@112=0x5588b7490e30 remaining@128=1
[RCE] *** SENTINEL EXECUTION MARKER FIRED *** arg=0x7ffeddcb4bc8 status=11 timeouts=0 callback=0x55888b4cbcf9
[result] done=1 status=11 accepted=1 follow_on_seen=1 normal_callbacks=1 forged_host_query=1 forged_callback_consumed=1 rce_marker_fired=1

Representative fixed negative-control evidence shows the same DNS boundary and allocator-forge opportunity but no stale consumption:

[server] accepted TCP DNS connection on 127.0.0.1:42041
[server] sending FORMERR without OPT for qid=24413
[server] sending second response with duplicate qid=24413 (NXDOMAIN, no OPT)
[server] observed follow-on search-domain query qid=24413 qtype=1 length=33
[server] resetting TCP connection with SO_LINGER zero
[allocator] FORGED_RECLAIM host_query ptr=0x55d50d23f020 callback@24=0x55d4d3286cb9 arg@32=0x7fff28da4f38 ai@112=0x55d50d2536f0 remaining@128=1
[result] done=1 status=11 accepted=1 follow_on_seen=1 normal_callbacks=1 forged_host_query=1 forged_callback_consumed=0 rce_marker_fired=0

Environment and source identity captured by the script:

vulnerable checkout v1.34.6 -> 3ac47ee46edd8ea40370222f91613fc16c434853
fixed checkout v1.34.7 -> d63b7de3a3568d14ab1351374b205365aed51cca
vulnerable ares_flush_requeue count: 0
fixed ares_flush_requeue count: 5

Recommendations / Next Steps

  • Upgrade c-ares deployments to v1.34.7 or later.
  • Preserve the fix pattern: detach queries from all lookup structures before invoking user callbacks, and centralize deferred requeue/endquery draining so callback reentrancy cannot rediscover pending query objects.
  • Add regression tests that exercise malicious TCP DNS peers, duplicate-QID/deferred ENDQUERY flows, TCP reset after follow-on query, and callback reentrancy.
  • Add allocator-assisted and sanitizer-backed tests that verify no stale host_query or ares_query fields are consumed after callback-driven reentrant cleanup.

Additional Notes

  • Idempotency confirmation: bundle/repro/reproduction_steps.sh was run successfully twice consecutively. The first successful full run observed 7 vulnerable marker firings out of 30 and 0 fixed marker firings out of 10. The second successful full run observed 4 vulnerable marker firings out of 30 and 0 fixed marker firings out of 10.
  • The vulnerable marker is probabilistic because it depends on the exact reentrant stale-use timing, so the script runs multiple bounded attempts and requires at least two vulnerable marker firings while ensuring the fixed build has zero marker firings.
  • The proof intentionally uses a benign in-process sentinel callback instead of executing an external command. No sanitizer is used for the primary code-execution proof.

CVE-2026-33630 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:003:35
0:00
session startedaccounts/fireworks/models/kimi-k2p7-code · CVE-2026-33630 · REPRO-20
0:03
0:05
web search
0:15
0:16
0:17
web search
0:27
0:28
1:18
1:18
extract_facts
no facts extracted
1:19
1:19
1:19
supportrepro
3:23
3:25
3:25
3:25
3:27
3:27
3:27
3:27
3:29
3:29
3:29
3:29
3:35
3:35
3:35
3:35
3:35
08 · How to Fix

How to Fix CVE-2026-33630

Upgrade c-ares/c-ares · c to 1.34.7 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-33630 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-33630

How does the c-ares exploitability demonstration work?

Under a real TCP DNS trigger combined with a deterministic public allocator-hook heap reclaim, the reproduction shows v1.34.6 executing a sentinel callback from a forged, reclaimed host_query structure - demonstrating that reclaimed callback fields can be consumed as control flow - while v1.34.7 never executes that marker.

Which c-ares versions are affected by CVE-2026-33630, and where is it fixed?

c-ares versions greater than 1.32.3 through 1.34.6 are affected; it is fixed in 1.34.7.

How severe is CVE-2026-33630, and is it a confirmed RCE?

It is rated high severity. The reproduction demonstrates that the use-after-free lets reclaimed host_query callback fields drive control flow in the vulnerable build - equivalent to a code-execution primitive when heap content is attacker-controlled - rather than shipping a fully weaponized, end-to-end RCE exploit.

How can I reproduce CVE-2026-33630?

Download the verified script from this page and run it in an isolated environment against c-ares v1.34.6; it drives the vulnerable ares_getaddrinfo() completion timing over TCP DNS with a deterministic allocator-hook heap reclaim and shows the forged host_query callback executing, then confirms v1.34.7 does not execute it.
11 · References

References for CVE-2026-33630

Authoritative sources for CVE-2026-33630 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.