Skip to content

Commit

Permalink
Fix PyCrypto routines at fork
Browse files Browse the repository at this point in the history
see https://lists.dlitz.net/pipermail/pycrypto/2013q4/000702.html

This fixes #23824

Signed-off-by: Mathieu Le Marec - Pasquet <kiorky@cryptelium.net>
  • Loading branch information
kiorky committed May 17, 2015
1 parent 72a8a77 commit f103da4
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 0 deletions.
3 changes: 3 additions & 0 deletions salt/minion.py
Expand Up @@ -23,6 +23,7 @@
# pylint: disable=import-error,no-name-in-module,redefined-builtin
import salt.ext.six as six
from salt.ext.six.moves import range
from salt.utils import reinit_crypto
# pylint: enable=no-name-in-module,redefined-builtin

# Import third party libs
Expand Down Expand Up @@ -653,8 +654,10 @@ def _post_master_init(self, master):
log.debug('Starting {0} proxy.'.format(p))
pid = os.fork()
if pid > 0:
reinit_crypto()
continue
else:
reinit_crypto()
proxyminion = ProxyMinion(self.opts)
proxyminion.start(self.opts['pillar']['proxy'][p])
self.clean_die(signal.SIGTERM, None)
Expand Down
6 changes: 6 additions & 0 deletions salt/modules/inspectlib/collector.py
Expand Up @@ -25,6 +25,7 @@
from salt.modules.inspectlib.dbhandle import DBHandle
from salt.modules.inspectlib.exceptions import (InspectorSnapshotException)
from salt.utils import fsutils
from salt.utils import reinit_crypto


class Inspector(object):
Expand Down Expand Up @@ -346,7 +347,10 @@ def main(dbfile, pidfile, mode):
# Double-fork stuff
try:
if os.fork() > 0:
reinit_crypto()
sys.exit(0)
else:
reinit_crypto()
except OSError as ex:
sys.exit(1)

Expand All @@ -356,11 +360,13 @@ def main(dbfile, pidfile, mode):
try:
pid = os.fork()
if pid > 0:
reinit_crypto()
fpid = open(pidfile, "w")
fpid.write("{0}\n".format(pid))
fpid.close()
sys.exit(0)
except OSError as ex:
sys.exit(1)

reinit_crypto()
main(dbfile, pidfile, mode)
27 changes: 27 additions & 0 deletions salt/utils/__init__.py
Expand Up @@ -43,6 +43,13 @@
# pylint: enable=import-error,redefined-builtin

# Try to load pwd, fallback to getpass if unsuccessful
# Import 3rd-party libs
try:
import Crypto.Random
HAS_CRYPTO = True
except ImportError:
HAS_CRYPTO = False

try:
import pwd
except ImportError:
Expand Down Expand Up @@ -330,6 +337,22 @@ def get_specific_user():
return user


def reinit_crypto():
'''
When a fork arrises, pycrypto needs to reinit
From its doc::
Caveat: For the random number generator to work correctly,
you must call Random.atfork() in both the parent and
child processes after using os.fork()
'''
ret = None
if HAS_CRYPTO:
ret = Crypto.Random.atfork()
return ret


def daemonize(redirect_out=True):
'''
Daemonize a process
Expand All @@ -338,6 +361,7 @@ def daemonize(redirect_out=True):
pid = os.fork()
if pid > 0:
# exit first parent
reinit_crypto()
sys.exit(salt.defaults.exitcodes.EX_OK)
except OSError as exc:
log.error(
Expand All @@ -355,6 +379,7 @@ def daemonize(redirect_out=True):
try:
pid = os.fork()
if pid > 0:
reinit_crypto()
sys.exit(salt.defaults.exitcodes.EX_OK)
except OSError as exc:
log.error(
Expand All @@ -364,6 +389,8 @@ def daemonize(redirect_out=True):
)
sys.exit(salt.defaults.exitcodes.EX_GENERIC)

reinit_crypto()

# A normal daemonization redirects the process output to /dev/null.
# Unfortunately when a python multiprocess is called the output is
# not cleanly redirected and the parent process dies when the
Expand Down
3 changes: 3 additions & 0 deletions salt/utils/vt.py
Expand Up @@ -46,6 +46,7 @@
import resource

# Import salt libs
from salt.utils import reinit_crypto
from salt.ext.six import string_types
from salt.log.setup import LOG_LEVELS

Expand Down Expand Up @@ -486,6 +487,7 @@ def __fork_ptys(self):
# Close parent FDs
os.close(stdout_parent_fd)
os.close(stderr_parent_fd)
reinit_crypto()

# ----- Make STDOUT the controlling PTY --------------------->
child_name = os.ttyname(stdout_child_fd)
Expand Down Expand Up @@ -546,6 +548,7 @@ def __fork_ptys(self):
# <---- Duplicate Descriptors --------------------------------
else:
# Parent. Close Child PTY's
reinit_crypto()
os.close(stdout_child_fd)
os.close(stderr_child_fd)

Expand Down

0 comments on commit f103da4

Please sign in to comment.