[issue18747] Re-seed OpenSSL's PRNG after fork

Charles-François Natali report at bugs.python.org
Wed Aug 21 16:46:08 CEST 2013


Charles-François Natali added the comment:

2013/8/21 Antoine Pitrou <report at bugs.python.org>:
> Instead of reseeding in the child, you can perturb the state in the parent
> after fork.
> As far as I understand, only the "child" callback in pthread_atfork() needs to be async-signal-safe:

That's not completely true: fork() is supposed to be async-signal
safe: it can be called from a signal handler (I wouldn't do this, but
that's allowed), but most notably, it can be called after another
fork().
For example, let's say you have a multi-threaded process, and it
fork()s. If you reseed from "parent" (right before or after fork),
then it's safe. But once you're in the child process, the process
state is "unsafe" until exec(), i.e. you can only call async-signal
safe functions. So if you fork() again before exec() - which is
common, e.g. if you use the double-fork() idiom for daemons - then
you'll call the reseed in an unsafe context. In other words, the
"parent" callback is called in the context of a "child" callback in
the child process.

So it's not really safe either, although the window is narrower.

The only 100% safe way I can think of - apart from ignoring the
problem - would be to check if the PID has changed upon entering ssl
function (caching it to avoid calling getpid() everytime), keeping in
mind that there will still be the risk of deadlock/crash anyway if the
user enters the ssl library before exec()...

Another, probably cleaner way would be to finally add the atfork()
module (issue #16500), and register this reseed hook (which could then
be implemented in ssl.py).

forking() in a multi-threaded context is an unsolvable problem...

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue18747>
_______________________________________


More information about the Python-bugs-list mailing list