From 6465b5334b5e7fcf7c8934ec18c1806a6a0a7b05 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Fri, 23 Sep 2022 13:52:57 -0700 Subject: [PATCH 1/5] gh-97514: Don't use Linux abstract sockets for multiprocessing. Linux abstract sockets are insecure as they lack any form of filesystem permissions so their use allows anyone on the system to inject code into the process. This removes the default preference for abstract sockets in multiprocessing introduced in Python 3.9+ via https://github.com/python/cpython/pull/18866 while fixing https://github.com/python/cpython/issues/84031. Explicit use of an abstract socket by a user now generates a RuntimeWarning. If we choose to keep this warning, it should be backported to the 3.7 and 3.8 branches. --- Lib/multiprocessing/connection.py | 27 ++++++++++++------- ...2-09-07-10-42-00.gh-issue-97514.Yggdsl.rst | 4 +++ 2 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 65303d29f51f8f..5fd2307a04041c 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -17,6 +17,7 @@ import time import tempfile import itertools +import warnings import _multiprocessing @@ -73,11 +74,6 @@ def arbitrary_address(family): if family == 'AF_INET': return ('localhost', 0) elif family == 'AF_UNIX': - # Prefer abstract sockets if possible to avoid problems with the address - # size. When coding portable applications, some implementations have - # sun_path as short as 92 bytes in the sockaddr_un struct. - if util.abstract_sockets_supported: - return f"\0listener-{os.getpid()}-{next(_mmap_counter)}" return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) elif family == 'AF_PIPE': return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % @@ -601,11 +597,22 @@ def __init__(self, address, family, backlog=1): self._family = family self._last_accepted = None - if family == 'AF_UNIX' and not util.is_abstract_socket_namespace(address): - # Linux abstract socket namespaces do not need to be explicitly unlinked - self._unlink = util.Finalize( - self, os.unlink, args=(address,), exitpriority=0 - ) + if family == 'AF_UNIX': + if util.is_abstract_socket_namespace(address): + self._unlink = None + warnings.warn( + 'Security: This application\'s use of an abstract socket ' + f'{address!r} for a multiprocessing Listener may allow ' + 'anyone on the system to inject code into the process.', + RuntimeWarning) + # XXX The stacklevel= `address` came from is not reasonably + # known because this could be constructed from multiple + # different levels based on how people use multiprocessing. + else: + # Linux abstract socket namespaces do not need to be explicitly unlinked + self._unlink = util.Finalize( + self, os.unlink, args=(address,), exitpriority=0 + ) else: self._unlink = None diff --git a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst new file mode 100644 index 00000000000000..2ee6c92d76efa1 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst @@ -0,0 +1,4 @@ +On Linux :mod:`multiprocessing` no longer uses Linux specific abstract socket +namespace sockets by default for inter-process communication as they have no +permissions and thus allowed anyone on the system to inject code into the +multiprocessing server process. From de8571d476261323ba358bd43142ee7c1fe0cb14 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Fri, 23 Sep 2022 14:57:53 -0700 Subject: [PATCH 2/5] Remove the warning. The right people won't see it and it won't blame the right code. --- Lib/multiprocessing/connection.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 5fd2307a04041c..b08144f7a1a169 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -17,7 +17,6 @@ import time import tempfile import itertools -import warnings import _multiprocessing @@ -597,22 +596,11 @@ def __init__(self, address, family, backlog=1): self._family = family self._last_accepted = None - if family == 'AF_UNIX': - if util.is_abstract_socket_namespace(address): - self._unlink = None - warnings.warn( - 'Security: This application\'s use of an abstract socket ' - f'{address!r} for a multiprocessing Listener may allow ' - 'anyone on the system to inject code into the process.', - RuntimeWarning) - # XXX The stacklevel= `address` came from is not reasonably - # known because this could be constructed from multiple - # different levels based on how people use multiprocessing. - else: - # Linux abstract socket namespaces do not need to be explicitly unlinked - self._unlink = util.Finalize( - self, os.unlink, args=(address,), exitpriority=0 - ) + if family == 'AF_UNIX' and not util.is_abstract_socket_namespace(address): + # Linux abstract socket namespaces do not need to be explicitly unlinked + self._unlink = util.Finalize( + self, os.unlink, args=(address,), exitpriority=0 + ) else: self._unlink = None From 8c5071403d6a7b254a7fc9e0e3875eff26fe55e1 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Thu, 13 Oct 2022 23:24:58 -0700 Subject: [PATCH 3/5] Reword NEWS, refer to CVE-2022-42919. --- ...2-09-07-10-42-00.gh-issue-97514.Yggdsl.rst | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst index 2ee6c92d76efa1..ada2d943943fa2 100644 --- a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst +++ b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst @@ -1,4 +1,16 @@ -On Linux :mod:`multiprocessing` no longer uses Linux specific abstract socket -namespace sockets by default for inter-process communication as they have no -permissions and thus allowed anyone on the system to inject code into the -multiprocessing server process. +On Linux the :mod:`multiprocessing` module when configured to use the +``"forkserver"`` start method has switched back to using filesystem backed unix +domain sockets by default for communication with the fork server. No longer +using Linux's abstract socket namespace by default. Abstract sockets have no +permissions and could thus allow any user on the system in the same `network +namespace `_ +(often the whole system) to inject code into the multiprocessing *forkserver* +process as a potential privilege escalation. Filesystem based socket +permissions are restricted to the forkserver user as with Python 3.8 and +earlier. + +This prevents Linux `CVE-2022-42919 +`_ in code that +chooses to use the *forkserver* start method as documented in +:ref:`multiprocessing contexts and start methods +`. From 4c3ce41c3c7d2fee9992774345f1859a228d89f6 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Tue, 18 Oct 2022 00:11:18 -0700 Subject: [PATCH 4/5] NEWS wording tweaks --- .../2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst index ada2d943943fa2..923b0db42a09f0 100644 --- a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst +++ b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst @@ -1,13 +1,13 @@ -On Linux the :mod:`multiprocessing` module when configured to use the -``"forkserver"`` start method has switched back to using filesystem backed unix -domain sockets by default for communication with the fork server. No longer -using Linux's abstract socket namespace by default. Abstract sockets have no -permissions and could thus allow any user on the system in the same `network +On Linux the :mod:`multiprocessing` module, when configured by code to use the +``"forkserver"`` start method, has switched back to using filesystem backed +unix domain sockets by default for communication with the *forkserver* process. +No longer using Linux's abstract socket namespace by default. Abstract sockets +have no permissions and could allow any user on the system in the same `network namespace `_ (often the whole system) to inject code into the multiprocessing *forkserver* process as a potential privilege escalation. Filesystem based socket -permissions are restricted to the forkserver user as with Python 3.8 and -earlier. +permissions are restricted to the *forkserver* process user as in Python 3.8 +and earlier. This prevents Linux `CVE-2022-42919 `_ in code that From 4f1b535a015d23b1bd4c61a76b070d94e941e632 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Thu, 20 Oct 2022 00:06:53 -0700 Subject: [PATCH 5/5] Reword the NEWS entry again. --- ...2-09-07-10-42-00.gh-issue-97514.Yggdsl.rst | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst index 923b0db42a09f0..02d95b570520df 100644 --- a/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst +++ b/Misc/NEWS.d/next/Security/2022-09-07-10-42-00.gh-issue-97514.Yggdsl.rst @@ -1,16 +1,15 @@ -On Linux the :mod:`multiprocessing` module, when configured by code to use the -``"forkserver"`` start method, has switched back to using filesystem backed -unix domain sockets by default for communication with the *forkserver* process. -No longer using Linux's abstract socket namespace by default. Abstract sockets -have no permissions and could allow any user on the system in the same `network -namespace `_ -(often the whole system) to inject code into the multiprocessing *forkserver* -process as a potential privilege escalation. Filesystem based socket -permissions are restricted to the *forkserver* process user as in Python 3.8 +On Linux the :mod:`multiprocessing` module returns to using filesystem backed +unix domain sockets for communication with the *forkserver* process instead of +the Linux abstract socket namespace. Only code that chooses to use the +:ref:`"forkserver" start method ` is affected. + +Abstract sockets have no permissions and could allow any user on the system in +the same `network namespace +`_ (often the +whole system) to inject code into the multiprocessing *forkserver* process. +This was a potential privilege escalation. Filesystem based socket permissions +restrict this to the *forkserver* process user as was the default in Python 3.8 and earlier. This prevents Linux `CVE-2022-42919 -`_ in code that -chooses to use the *forkserver* start method as documented in -:ref:`multiprocessing contexts and start methods -`. +`_.