Skip to content

gh-137335: Fix unlikely name conflicts for named pipes in multiprocessing and asyncio on Windows #137389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Aug 4, 2025

Since os.stat() raises an OSError for existing named pipe "\\.\pipe\...", os.path.exists() always returns False for it, and tempfile.mktemp() can return a name that matches an existing named pipe.

So, tempfile.mktemp() cannot be used to generate unique names for named pipes. Instead, CreateNamedPipe() should be called in a loop with different names until it completes successfully.

…processing and asyncio on Windows

Since os.stat() raises an OSError for existing named pipe "\\.\pipe\...",
os.path.exists() always returns False for it, and tempfile.mktemp() can
return a name that matches an existing named pipe.

So, tempfile.mktemp() cannot be used to generate unique names for named
pipes. Instead, CreateNamedPipe() should be called in a loop with
different names until it completes successfully.
@serhiy-storchaka serhiy-storchaka added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes labels Aug 4, 2025
@serhiy-storchaka serhiy-storchaka changed the title gh-137335: Fix unlikely nmae conflicts for named pipes in multiprocessing and asyncio on Windows gh-137335: Fix unlikely name conflicts for named pipes in multiprocessing and asyncio on Windows Aug 4, 2025
address, openmode, _winapi.PIPE_WAIT,
1, obsize, ibsize, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL)
while True:
address = r'\\.\pipe\python-pipe-' + random.randbytes(8).hex()
Copy link
Member

@picnixz picnixz Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment:

we could use os.urandom(8).hex() but this would only reduce the number of loop iterations we would do until we find a suitable name. OTOH, this makes normal cases much slower (usually, we are not in the presence of an adversary that is trying to create pipes...), so we would be only doing the loop once.

Now, I'm actually worried that it if we're able to interact with the process that is creating the pipes, then we could actually recover enough samples from the underlying PRNG instance and get the original seed. But this is only if 1) there are no random calls in between and 2) we can get 624 consecutive 32-bit samples from the random source.

Condition 2) already holds because random.randbytes(8) is actually equivalent to two calls of random.randbytes(4) that are concatenated. Since reverting MT-19937 requires only consecutive 624 32-bit words, this is the same as doing 312 pipe creations where we don't have calls to random.* in between (and then inspect the named file). This could be possible in practice, especially if we're talking about the multiprocessing and the asyncio components which could have some interactivness (e.g., a server).

Therefore, I would still suggest using os.urandom(8).hex() even if it slows down the calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy