AnyIO Process-Pool Stderr Pipe Deadlock, Denial of Service, CVE-2026-64847 (Moderate) -DC-Sep2026-2494

Listen to this Post

How CVE-2026-64847 Works

AnyIO is a Python library that provides a unified asynchronous API across asyncio and trio. It is widely used to manage concurrent tasks, threads, and subprocesses in modern Python applications. One of its features, to_process.run_sync(), allows developers to offload CPU-intensive synchronous functions to worker processes. These workers communicate with the parent process through a dedicated protocol over standard streams.
The vulnerability lies in how AnyIO initializes these worker processes. When a process-pool worker starts, AnyIO connects the worker’s `stderr` to a pipe. The parent process holds the read end of this pipe but never drains it. The worker redirects `stdin` and `stdout` to `/dev/null` to protect the integrity of its internal communication protocol, but it does not redirect stderr, despite documentation claiming that all three standard streams are redirected.
The pipe used for `stderr` has a limited buffer size, typically 64 KB on Linux. When a worker function writes data to sys.stderr, that data accumulates in the pipe buffer. If the worker writes enough data to exceed the buffer capacity, the `write()` system call blocks. The worker process becomes stuck at that point and cannot continue executing. It never returns to the point where it would send its protocol response over stdout.
On the other side, the parent process is awaiting the result of the worker call. The parent does not read from the `stderr` pipe, so the buffer never empties. The worker remains blocked indefinitely, and the parent’s process-pool call never completes. This results in a permanent deadlock.
The attack surface is broad. Any code executed through `to_process.run_sync()` that writes an attacker-controlled amount of data to `stderr` can trigger the deadlock. This includes functions that log verbose output, print progress indicators, or process untrusted data that may contain large error messages. An attacker who can influence the input to such a function can cause a denial of service by filling the `stderr` pipe and wedging the worker process.
The vulnerability was assigned CVE-2026-64847 and carries a CVSS score of 6.8, indicating moderate severity. The fix introduced in AnyIO v4.14.2 redirects the worker’s `sys.stderr` to os.devnull, matching the documented behavior and eliminating the undrained pipe entirely.

DailyCVE Form

Platform: AnyIO
Version: < 4.14.2
Vulnerability: Stderr Pipe Deadlock
Severity: Moderate
date: 2026-07-07

Prediction: 2026-07-12

What Undercode Say

Analytics

The vulnerability exists in anyio/_backends/_asyncio.py and anyio/to_process.py. The worker process setup code redirects `stdin` and `stdout` but omits stderr:

Worker process initialization (vulnerable)
async def _worker_process_main(...):
Redirect stdin and stdout to /dev/null
sys.stdin = open(os.devnull)
sys.stdout = open(os.devnull, 'w')
sys.stderr is NOT redirected — remains connected to undrained pipe

The parent process holds the read end of the `stderr` pipe but never reads from it:

Parent side — pipe created but never drained
async def run_sync(func, args):
parent_conn, child_conn = ... pipe
process = await spawn_worker(...)
stderr pipe read end is never read
result = await read_protocol_response(process)

To verify if an application is vulnerable, check the AnyIO version:

pip show anyio | grep Version

To check if `stderr` redirection is present in the installed version:

import anyio.to_process
import inspect
source = inspect.getsource(anyio.to_process)
print("devnull" in source and "stderr" in source)

Exploit: (Educational Purposes!)

The following code demonstrates the deadlock condition. Run this only in an isolated environment.

import anyio
from anyio import to_process
import sys
def malicious_worker():
Write enough data to fill the 64KB stderr pipe buffer
This blocks once the buffer is full
for i in range(100000):
sys.stderr.write(f"Filling stderr buffer: {i}\n")
sys.stderr.flush()
return "should never reach here"
async def main():
print("Starting worker — will deadlock...")
result = await to_process.run_sync(malicious_worker)
print(f"Result: {result}") Never reached
if <strong>name</strong> == "<strong>main</strong>":
anyio.run(main)

The worker writes line after line to stderr. Once the pipe buffer fills, the `write()` call blocks. The worker never returns, the protocol response is never sent, and the parent waits forever.

Protection: from this CVE

Upgrade to AnyIO v4.14.2 or later. This is the only complete fix. The patched version redirects `sys.stderr` to `os.devnull` in worker processes.

pip install --upgrade anyio>=4.14.2

Workaround for versions prior to 4.14.2: Close `sys.stderr` inside the target function before writing anything to it.

import sys
def safe_worker():
sys.stderr.close() Prevents any write from blocking
function logic continues without stderr
return "completed"

This workaround prevents the deadlock but suppresses all diagnostic output from the worker. It should be treated as a temporary measure until the upgrade can be applied.

Impact

  • Denial of Service: Worker processes block indefinitely, consuming pool slots and preventing further tasks from executing.
  • Application Hang: Any application awaiting `to_process.run_sync()` will hang permanently, requiring manual process termination.
  • Resource Exhaustion: Blocked workers hold memory and process handles, leading to gradual resource depletion under repeated exploitation.
  • Scope: All AnyIO versions prior to 4.14.2 are affected. Any application that passes untrusted or verbose code to `to_process.run_sync()` is at risk.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top