[Python-Dev] PEP 433: Add cloexec argument to functions creating file descriptors

Nick Coghlan ncoghlan at gmail.com
Sun Jan 13 14:49:32 CET 2013


On Sun, Jan 13, 2013 at 11:22 PM, Antoine Pitrou <solipsis at pitrou.net> wrote:
> On Sun, 13 Jan 2013 22:44:06 +1000
> Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On Sun, Jan 13, 2013 at 9:43 PM, Antoine Pitrou <solipsis at pitrou.net> wrote:
>> > As for the opacity, feel free to propose something better
>> > ("close_on_spawn", whatever). But I'm definitely and strongly -1
>> > on "noinherit".
>>
>> That's the main reason I quite like "sensitive" as a term for this,
>> since it decouples the user statement ("this file descriptor provides
>> access to potentially sensitive information") from the steps the
>> interpreter promises to take to protect that information (such as
>> closing it before executing a different program or ensuring it isn't
>> inherited by child processes).
>
> This assumes that some file descriptors are not "sensitive", which
> sounds a bit weird to me (since a fd will by definition give access
> to a system resource). What should happen is that *no* file descriptors
> are inherited on exec(), except for those few ones which are necessary
> for proper operation of the exec()ed process.

I agree it makes it obvious what the right default behaviour should
be: flag every FD as sensitive by default, and pass an argument to say
"sensitive=False" when you want to disable Python's automatic
protections.

However, there's a pragmatic question of whether we're willing to eat
the backwards incompatibility of such a change in a feature release,
or if it's something that has to wait until Python 4.0, or else be
selected via a global flag (in line with the hash randomisation
change).

> (it's not even just a security issue: letting a bound socket open and
> therefore being unable to re-use the same port is a bug even when
> security is not a concern)

Agreed, but it's the security implications that let us even
contemplate the backwards compatibility break. We either let
inexperienced users continue to write insecure software by default, or
we close the loophole and tell experienced users "hey, to upgrade to
Python 3.4, you will need to address this change in behaviour".

The nice thing is that with enough advance warning, they should be
able to update their code to forcibly clear the flag in a way that
works even on earlier Python versions.

A more conservative approach, based on the steps taken in introducing
hash randomisation, would be to expose the setting as an environment
variable in 3.4, and then switch the default behaviour in 3.5.

So, 3.3: FDs non-sensitive by default, use O_CLOEXEC, noinherit, etc
directly for sensitive ones
3.4: FDs non-sensitive by default, set "sensitive=True" to enable
selectively, or set PYTHONSENSITIVEFDS to enable globally and
"sensitive=False" to disable selectively
3.5: FDs sensitive by default, set "sensitive=False" to enable
selectively, no PYTHONSENSITIVEFDS setting

(To accelerate the adoption schedule, replace 3.5 with 3.4, and 3.4
with 3.3.1, but require that people set or clear the platform specific
flags to work around the default behaviour)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list