CVE-2024-21626
runc vulnerable to container breakout through process.cwd trickery and leaked fds
Summary
### Impact In runc 1.1.11 and earlier, due to an internal file descriptor leak, an attacker could cause a newly-spawned container process (from `runc exec`) to have a working directory in the host filesystem namespace, allowing for a container escape by giving access to the host filesystem ("attack 2"). The same attack could be used by a malicious image to allow a container process to gain access to the host filesystem through `runc run` ("attack 1"). Variants of attacks 1 and 2 could be also be used to overwrite semi-arbitrary host binaries, allowing for complete container escapes ("attack 3a" and "attack 3b"). Strictly speaking, while attack 3a is the most severe from a CVSS perspective, attacks 2 and 3b are arguably more dangerous in practice because they allow for a breakout from inside a container as opposed to requiring a user execute a malicious image. The reason attacks 1 and 3a are scored higher is because being able to socially engineer users is treated as a given for UI:R vectors, despite attacks 2 and 3b requiring far more minimal user interaction (just reasonable `runc exec` operations on a container the attacker has access to). In any case, all four attacks can lead to full control of the host system. #### Attack 1: `process.cwd` "mis-configuration" In runc 1.1.11 and earlier, several file descriptors were inadvertently leaked internally within runc into `runc init`, including a handle to the host's `/sys/fs/cgroup` (this leak was added in v1.0.0-rc93). If the container was configured to have `process.cwd` set to `/proc/self/fd/7/` (the actual fd can change depending on file opening order in `runc`), the resulting pid1 process will have a working directory in the host mount namespace and thus the spawned process can access the entire host filesystem. This alone is not an exploit against runc, however a malicious image could make any innocuous-looking non-`/` path a symlink to `/proc/self/fd/7/` and thus trick a user into starting a container whose binary has access to the host filesystem. Furthermore, prior to runc 1.1.12, runc also did not verify that the final working directory was inside the container's mount namespace after calling `chdir(2)` (as we have already joined the container namespace, it was incorrectly assumed there would be no way to chdir outside the container after `pivot_root(2)`). The CVSS score for this attack is CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N (8.2, high severity). Note that this attack requires a privileged user to be tricked into running a malicious container image. It should be noted that when using higher-level runtimes (such as Docker or Kubernetes), this exploit can be considered critical as it can be done remotely by anyone with the rights to start a container image (and can be exploited from within Dockerfiles using `ONBUILD` in the case of Docker). #### Attack 2: `runc exec` container breakout (This is a modification of attack 1, constructed to allow for a process inside a container to break out.) The same fd leak and lack of verification of the working directory in attack 1 also apply to `runc exec`. If a malicious process inside the container knows that some administrative process will call `runc exec` with the `--cwd` argument and a given path, in most cases they can replace that path with a symlink to `/proc/self/fd/7/`. Once the container process has executed the container binary, `PR_SET_DUMPABLE` protections no longer apply and the attacker can open `/proc/$exec_pid/cwd` to get access to the host filesystem. `runc exec` defaults to a cwd of `/` (which cannot be replaced with a symlink), so this attack depends on the attacker getting a user (or some administrative process) to use `--cwd` and figuring out what path the target working directory is. Note that if the target working directory is a parent of the program binary being executed, the attacker might be unable to replace the path with a symlink (the `execve` will fail in most cases, unless the host
Affected packages
| Ecosystem | Package | Affected versions | Fixed versions |
|---|---|---|---|
| Go | github.com/opencontainers/runc | — | 1.1.12 |
Remediation: Upgrade to 1.1.12 or later.
References
Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.
CVE® is a registered trademark of The MITRE Corporation. CVE content reproduced under the CVE Terms of Use; copyright designation © MITRE.
EPSS scores provided by the FIRST.org Exploit Prediction Scoring System.