GitHub Security Advisory: GHSA-9493-h29p-rfm2
Package: github.com/opencontainers/runc (GO)
Severity: HIGH (CVSS 0.0)
CWE: CWE-61: UNIX Symbolic Link (Symlink) Following, CWE-363: Race Condition Enabling Link Following
Vulnerable versions: >= 1.4.0-rc.1, <= 1.4.0-rc.2
Patched in: 1.4.0-rc.3

Summary: runc container escape via "masked path" abuse due to mount race conditions

Details:
### Impact ###  
The OCI runtime specification has a `maskedPaths` feature that allows for files or directories to be "masked" by placing a mount on top of them to conceal their contents. This is primarily intended to protect against privileged users in non-user-namespaced from being able to write to files or access directories that would either provide sensitive information about the host to containers or allow containers to perform destructive or other privileged operations on the host (examples include `/proc/kcore`, `/proc/timer_list`, `/proc/acpi`, and `/proc/keys`).  

`maskedPaths` can be used to either mask a directory or a file -- directories are masked using a new read-only `tmpfs` instance that is mounted on top of the masked path, while files are masked by bind-mounting the container's `/dev/null` on top of the masked path.  

In all known versions of runc, when using the container's `/dev/null` to mask files, runc would not perform sufficient verification that the source of the bind-mount (i.e., the container's `/dev/null`) was actually a real `/dev/null` inode. While `/dev/null` is usually created by runc when doing container creation, it is possible for an attacker to create a `/dev/null` or modify the `/dev/null` inode created by runc through race conditions with other containers sharing mounts (runc has also verified this attack is possible to exploit using a standard Dockerfile with `docker buildx build` as that also permits triggering parallel execution of containers with custom shared mounts configured).  

This could lead to two separate issues:  

#### Attack 1: Arbitrary Mount Gadget (leading to Host Information Disclosure, Host Denial of Service, or Container Escape) ####  
By replacing `/dev/null` with a symlink to an attacker-controlled path, an attacker could cause runc to bind-mount an arbitrary source path to a path inside the container. This could lead to:  
* **Host Denial of Service**: By bind-mounting files such as `/proc/sysrq-trigger`, the attacker can gain access to a read-write version of files which can be destructive to write to (`/proc/sysrq-trigger` would allow an attacker to trigger a kernel panic, shutting down the machine, or causing the machine to freeze without rebooting).  
* **Container Escape**: By bind-mounting `/proc/sys/kernel/core_pattern`, the attacker can reconfigure a coredump helper -- as kernel upcalls are not namespaced, the configured binary (which could be a container binary or a host binary with a malicious command-line) will run with full privileges on the host system. Thus, the attacker can simply trigger a coredump and gain complete root privileges over the host.  

Note that while `config.json` allows users to bind-mount arbitrary paths (and thus an attacker that can modify `config.json` arbitrarily could gain the same access as this exploit), because `maskedPaths` is applied by almost all higher-level container runtimes (and thus provides a guaranteed mount source) this flaw effec