Python 3.9.x before 3.9.16 and 3.10.x before 3.10.9 on Linux allows local privilege escalation in a non-default configuration. The Python multiprocessing library, when used with the forkserver start method on Linux, allows pickles to be deserialized from any user in the same machine local network namespace, which in many system configurations means any user on the same machine. Pickles can execute arbitrary code. Thus, this allows for local user privilege escalation to the user that any forkserver process is running as. Setting multiprocessing.util.abstract_sockets_supported to False is a workaround. The forkserver start method for multiprocessing is not the default start method. This issue is Linux specific because only Linux supports abstract namespace sockets. CPython before 3.9 does not make use of Linux abstract namespace sockets by default. Support for users manually specifying an abstract namespace socket was added as a bugfix in 3.7.8 and 3.8.3, but users would need to make specific uncommon API calls in order to do that in CPython before 3.9.
## TL;DR

Python 3.9, 3.10, and 3.11.0rc2 on Linux may allow for a local privilege escalation attack in a non-default configuration when code uses the `multiprocessing` module and configures `multiprocessing` to use the *forkserver* start method.

## Details

The Python `multiprocessing` library, when used with the *forkserver* start method on Linux, allows Python pickles to be deserialized from any user in the same machine local network namespace, which in many system configurations means any user on the same machine. Pickles can execute arbitrary code. Thus, this allows for local user privilege escalation to the user that any Python multiprocessing *forkserver* process is running as.

The forkserver start method for multiprocessing is not the default start method. This issue is Linux specific because only Linux supports abstract namespace sockets.

CPython before 3.9 does not make use of Linux abstract namespace sockets by default.

This issue has been assigned [CVE-2022-42919](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42919).

Credit: This issue was discovered by Devin Jeanpierre (@ssbr) of Google.

### Are Python 3.7 and 3.8 affected?

Not by default.

Support for users manually specifying an abstract namespace AF_UNIX socket was added [as a bugfix](https://github.com/python/cpython/issues/84031) in 3.7.8 and 3.8.3, but users would need to make specific uncommon `multiprocessing` API calls specifying their own *forkserver* control socket path in order to do that in CPython before 3.9.

### What about code that explicitly asks for an abstract socket?

Applications found to be making the uncommon `multiprocessing` API calls to explicitly use Linux abstract namespace sockets with a *forkserver* are believed to be rare and should have their own specific security issues filed.

## Workarounds

### From Python application or library code:

```python
import multiprocessing.util
multiprocessing.util.abstract_sockets_supported = False
```

This disables their use by default. You must execute that before anything else in your process has started making use of multiprocessing.

### If you can patch your CPython runtime itself:

Remove these two lines from CPython's [`Lib/multiprocessing/connection.py`](https://github.com/python/cpython/blob/1699128c4891da3bbe23553d709261d88855b93f/Lib/multiprocessing/connection.py#L79-L80):

```diff
-        if util.abstract_sockets_supported:
-            return f"\0listener-{os.getpid()}-{next(_mmap_counter)}"
```

_(that is what our security bug fix commits do)._

Or, similar to the application level fix, edit [`Lib/multiprocessing/util.py`](https://github.com/python/cpython/blob/1699128c4891da3bbe23553d709261d88855b93f/Lib/multiprocessing/util.py#L126) to always set:

```diff
- abstract_sockets_supported = _platform_supports_abstract_sockets()
+ abstract_sockets_supported = False
```

### Alternatives to avoid the problem

If your Linux Python application can be switched from multiprocessing's `.set_start_method("forkserver")` to a start method such as `"spawn"` that will also avoid this issue.

## Scope of the bug fixes

We are changing the default in Python 3.9 and higher to not use the Linux abstract namespace sockets by default.

It would be ideal to add authentication to the *forkserver* control socket so that it isn't even relying on filesystem permissions. This is a more complicated change and is expected to be done as a feature in 3.12.



### Tasks
- [x] Cherry pick the 3.11 commit to the 3.11.0 release. https://github.com/python/cpython/commit/4686d77a04570a663164c03193d9def23c89b122
- [x] Merge the 3.9 PR. https://github.com/python/cpython/pull/98504
- [x] After 3.11.0 is out, make sure 3.11.1 won't have a duplicate news entry about this due to the branch vs 3.11.0 release branch
- [ ] Push @gpshead 's PR(s) for proper forkserver socket authentication in 3.12.





<!-- gh-pr-number: gh-99309 -->
### Linked PRs
* PR: gh-99309
<!-- /gh-pr-number -->

Linux specific local privilege escalation via the multiprocessing forkserver start method - CVE-2022-42919
This is a GitHub Issue
repo:cpython
owner:python
Title : Linux specific local privilege escalation via the multiprocessing forkserver start method - CVE-2022-42919
Issue date:

--- start body ---
## TL;DR

Python 3.9, 3.10, and 3.11.0rc2 on Linux may allow for a local privilege escalation attack in a non-default configuration when code uses the `multiprocessing` module and configures `multiprocessing` to use the *forkserver* start method.

## Details

The Python `multiprocessing` library, when used with the *forkserver* start method on Linux, allows Python pickles to be deserialized from any user in the same machine local network namespace, which in many system configurations means any user on the same machine. Pickles can execute arbitrary code. Thus, this allows for local user privilege escalation to the user that any Python multiprocessing *forkserver* process is running as.

The forkserver start method for multiprocessing is not the default start method. This issue is Linux specific because only Linux supports abstract namespace sockets.

CPython before 3.9 does not make use of Linux abstract namespace sockets by default.

This issue has been assigned [CVE-2022-42919](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42919).

Credit: This issue was discovered by Devin Jeanpierre (@ssbr) of Google.

### Are Python 3.7 and 3.8 affected?

Not by default.

Support for users manually specifying an abstract namespace AF_UNIX socket was added [as a bugfix](https://github.com/python/cpython/issues/84031) in 3.7.8 and 3.8.3, but users would need to make specific uncommon `multiprocessing` API calls specifying their own *forkserver* control socket path in order to do that in CPython before 3.9.

### What about code that explicitly asks for an abstract socket?

Applications found to be making the uncommon `multiprocessing` API calls to explicitly use Linux abstract namespace sockets with a *forkserver* are believed to be rare and should have their own specific security issues filed.

## Workarounds

### From Python application or library code:

```python
import multiprocessing.util
multiprocessing.util.abstract_sockets_supported = False
```

This disables their use by default. You must execute that before anything else in your process has started making use of multiprocessing.

### If you can patch your CPython runtime itself:

Remove these two lines from CPython's [`Lib/multiprocessing/connection.py`](https://github.com/python/cpython/blob/1699128c4891da3bbe23553d709261d88855b93f/Lib/multiprocessing/connection.py#L79-L80):

```diff
-        if util.abstract_sockets_supported:
-            return f"\0listener-{os.getpid()}-{next(_mmap_counter)}"
```

_(that is what our security bug fix commits do)._

Or, similar to the application level fix, edit [`Lib/multiprocessing/util.py`](https://github.com/python/cpython/blob/1699128c4891da3bbe23553d709261d88855b93f/Lib/multiprocessing/util.py#L126) to always set:

```diff
- abstract_sockets_supported = _platform_supports_abstract_sockets()
+ abstract_sockets_supported = False
```

### Alternatives to avoid the problem

If your Linux Python application can be switched from multiprocessing's `.set_start_method("forkserver")` to a start method such as `"spawn"` that will also avoid this issue.

## Scope of the bug fixes

We are changing the default in Python 3.9 and higher to not use the Linux abstract namespace sockets by default.

It would be ideal to add authentication to the *forkserver* control socket so that it isn't even relying on filesystem permissions. This is a more complicated change and is expected to be done as a feature in 3.12.



### Tasks
- [x] Cherry pick the 3.11 commit to the 3.11.0 release. https://github.com/python/cpython/commit/4686d77a04570a663164c03193d9def23c89b122
- [x] Merge the 3.9 PR. https://github.com/python/cpython/pull/98504
- [x] After 3.11.0 is out, make sure 3.11.1 won't have a duplicate news entry about this due to the branch vs 3.11.0 release branch
- [ ] Push @gpshead 's PR(s) for proper forkserver socket authentication in 3.12.





<!-- gh-pr-number: gh-99309 -->
### Linked PRs
* PR: gh-99309
<!-- /gh-pr-number -->

--- end body ---
