{"id":"GHSA-5qpg-rh4j-qp35","summary":"pycares has a Use-After-Free Vulnerability","details":"## Summary\n\npycares is vulnerable to a use-after-free condition that occurs when a Channel object is garbage collected while DNS queries are still pending. This results in a fatal Python error and interpreter crash.\n\n## Details\n\n### Root Cause\n\nThe vulnerability stems from improper handling of callback references when the Channel object is destroyed:\n\n1. When a DNS query is initiated, pycares stores a callback reference using `ffi.new_handle()`\n2. If the Channel object is garbage collected while queries are pending, the callback references become invalid\n3. When c-ares attempts to invoke the callback, it accesses freed memory, causing a fatal error\n\nThis issue was much more likely to occur when using `event_thread=True` but could happen without it under the right circumstances.\n\n### Technical Details\n\nThe core issue is a race condition between Python's garbage collector and c-ares's callback execution:\n\n1. When `__del__` is called from within a c-ares callback context, we cannot immediately call `ares_destroy()` because c-ares is still executing code after the callback returns\n2. c-ares needs to execute cleanup code after our Python callback returns (specifically at lines 1422-1429 in ares_process.c)\n3. If we destroy the channel too quickly, c-ares accesses freed memory\n\n### Impact\n\nApplications using `pycares` can be crashed remotely by triggering DNS queries that result in `Channel` objects being garbage collected before query completion. This is particularly problematic in scenarios where:\n\n- Channel objects are created per-request\n- Multiple failed DNS queries are processed rapidly\n- The application doesn't properly manage Channel lifecycle\n\nThe error manifests as:\n```\nFatal Python error: b_from_handle: ffi.from_handle() detected that the address passed points to garbage\n```\n\n## Fix\n\nThe vulnerability has been fixed in pycares 4.9.0 by implementing a safe channel destruction mechanism\n\n## Mitigation\n\n### For Application Developers\n\n1. **Upgrade to pycares \u003e= 4.9.0** - This version includes the fix and requires no code changes\n2. **Best practices** (optional but recommended):\n   ```python\n   # Explicit cleanup\n   channel.close()\n   \n   # Or use context manager\n   with pycares.Channel() as channel:\n       # ... use channel ...\n   # Automatically closed\n   ```\n3. **Avoid creating Channel objects per-request** - Prefer long-lived instances for better performance and safety\n\nThe fix is completely transparent - no API changes or code modifications are required.\n\n## Credit\n\nThis vulnerability was reported by @vEpiphyte through the aio-libs security program.","aliases":["CVE-2025-48945"],"modified":"2026-09-10T03:50:24.913361759Z","published":"2025-06-16T16:09:47Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2025-06-16T16:09:47Z","nvd_published_at":null,"cwe_ids":["CWE-416"],"severity":"MODERATE"},"references":[{"type":"WEB","url":"https://github.com/saghul/pycares/security/advisories/GHSA-5qpg-rh4j-qp35"},{"type":"WEB","url":"https://github.com/saghul/pycares/commit/ebfd7d71eb8e74bc1057a361ea79a5906db510d4"},{"type":"PACKAGE","url":"https://github.com/saghul/pycares"}],"affected":[{"package":{"name":"pycares","ecosystem":"PyPI","purl":"pkg:pypi/pycares"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.9.0"}]}],"versions":["0.1.0","0.2.0","0.3.0","0.4.0","0.5.0","0.6.0","0.6.1","0.6.2","0.6.3","0.7.0","1.0.0","2.0.0","2.0.1","2.1.0","2.1.1","2.2.0","2.3.0","2.4.0","3.0.0","3.0.0b0","3.0.0b1","3.0.0b2","3.0.0b3","3.0.0b4","3.0.0b5","3.1.0","3.1.1","3.2.0","3.2.3","4.0.0","4.1.1","4.1.2","4.2.0","4.2.1","4.2.2","4.3.0","4.4.0","4.5.0","4.6.0","4.6.1","4.7.0","4.8.0"],"database_specific":{"last_known_affected_version_range":"\u003c= 4.8.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/06/GHSA-5qpg-rh4j-qp35/GHSA-5qpg-rh4j-qp35.json"}}],"schema_version":"1.9.0"}