@@ -23,6 +23,12 @@ class TimeoutError(ProcessError):
2323class AuthenticationError (ProcessError ):
2424 pass
2525
26+ # The default digest for multiprocessing.connection to use for auth.
27+ # We configure it here so that it can be tested when choosing a
28+ # default context without a circular import.
29+ # Must be the str of a value seen in connection._ALLOWED_DIGESTS.
30+ _DIGEST_FOR_CONNECTION_HMAC = 'sha256'
31+
2632#
2733# Base type for contexts. Bound methods of an instance of this type are included in __all__ of __init__.py
2834#
@@ -313,6 +319,21 @@ class ForkServerContext(BaseContext):
313319 def _check_available (self ):
314320 if not reduction .HAVE_SEND_HANDLE :
315321 raise ValueError ('forkserver start method not available' )
322+ if not _test_if_connection_can_work ():
323+ raise ValueError (f'forkserver start method not available due to missing hmac-{ _DIGEST_FOR_CONNECTION_HMAC } ' )
324+
325+ def _test_if_connection_can_work () -> bool :
326+ # Authenticated connections required for forkserver using hmac.
327+ # If the algorithm is unavailable (poor FIPS mode config?) at
328+ # import time, we cannot default to forkserver. If a user
329+ # changes the _DIGEST_FOR_CONNECTION_HMAC to one that works in
330+ # their strange config, the forkserver context will still work.
331+ import hmac
332+ try :
333+ hmac .new (b'test-key' * 8 , b'' , _DIGEST_FOR_CONNECTION_HMAC )
334+ except ValueError :
335+ return False
336+ return True
316337
317338 _concrete_contexts = {
318339 'fork' : ForkContext (),
@@ -322,7 +343,8 @@ def _check_available(self):
322343 # bpo-33725: running arbitrary code after fork() is no longer reliable
323344 # on macOS since macOS 10.14 (Mojave). Use spawn by default instead.
324345 # gh-84559: We changed everyones default to a thread safeish one in 3.14.
325- if reduction .HAVE_SEND_HANDLE and sys .platform != 'darwin' :
346+ if (reduction .HAVE_SEND_HANDLE and sys .platform != 'darwin' and
347+ _test_if_connection_can_work ()):
326348 _default_context = DefaultContext (_concrete_contexts ['forkserver' ])
327349 else :
328350 _default_context = DefaultContext (_concrete_contexts ['spawn' ])
0 commit comments