[Python-Dev] Proposal for a new function "open_noinherit" to avoid problems with subprocesses and security risks

Henning von Bargen henning.vonbargen at arcor.de
Sat Jun 23 10:04:33 CEST 2007

OT: Argh - my email address is visible in the posting - I am doomed!

----- Original Message ----- 
> Martin v. Löwis wrote:
> Do you have a patch implementing that feature? I believe
> it's unimplementable in Python 2.x: open() is mapped
> to fopen(), which does not support O_NOINHERIT.

Yes, I have a patch implemented in pure Python.

I got the code on my workplace PC (now I am writing from home,
that's why I said I'll post the code later).

The patch uses os.fdopen ( os.open (..., ...), ...).
It translates IOError into OSError then to raise the same class
of exception aso open().

Unfortunately, the patch is ignoring the bufsize argument,
so it is only a protoype at this time.

I know that open() is mapped to fopen() and fopen does not
support close_fds.
Thus a correct patch has to be implemented at the C level.
It should use open and fdopen instead of fopen - just like the
Python prototype.
AFAIK in the C stdlib implementation, fopen is implemented
based on open anyway.
BTW to find out what happens, I had to look to the source distribution
for the first time after 3 years of using Python.

> If you don't want the subprocess to inherit handles,
> why don't you just specify close_fds=True when creating
> the subprocess?

The subprocess module is a great piece of code,
but it has its weeknesses. "close_fds" is one of them.
subprocess.py fails on MS Windows if I specify close_fds.

And it *cannot* be fixed for MS Windows in the subprocess module.
This is due to the different way MS Windows handles handles :-)
in child process creation:

In Posix, you can just work through the file numbers range
and close the ones you don't want/need in the subprocess.
This is how close_fds works internally.
It closes the fds starting from 3 to MAX_FDs-1, thus only stdin,
stdout and stderr are inherited.

On MS Windows, AFAIK (correct me if I am wrong), you can
only choose either to inherit handles or not *as a whole*
 - including stdin, stdout and stderr -, when calling CreateProcess.
Each handle has a security attribute that specifies whether the
handle should be inherited or not - but this has to be specified
when creating the handle (in the Windows CreateFile API internally).
Thus, on MS Windows, you can either choose to inherit all
files opened with "open" + [stdin, stdout, stderr],
or to not inherit any files (meaning even stdin, stdout and stderr
will not be inherited).

In a platform-independent program, close_fds is therefore not an option.


More information about the Python-Dev mailing list