Runc is a CLI tool that creates and runs containers based on the OCI (Open Container Initiative) standard. Currently, the docker engine is also internally built based on runc. On February 11, 2019, researchers revealed details of runc container breakout vulnerabilities through the oss-security mailing list. The assigned CVE for this issue is CVE-2019-5736. According to OpenWall, exploit details will be publicized seven days later, February 18, 2019. The vulnerability may affect the majority of cloud service providers, and the damage is serious.
The vulnerability allows a malicious container (with minimal user interaction) to overwrite the runc file on the host to execute code with root privileges on the host. In the following two cases, arbitrary code can be executed in the container with root privileges through user interaction:
* Creating a new container using an attacker-controlled image.
* Attaching (docker exec) into an existing container which the attacker had previous write access to.
This vulnerability is *not* blocked by the default AppArmor policy, nor by the default SELinux policy on Fedora[++] (because container processes appear to be running as container_runtime_t). However, it *is* blocked
through correct use of user namespaces (where the host root is not mapped into the container’s user namespace).
An attacker can spoof runc to execute itself by replacing the object file in the container with his own file pointing to runc. For example, the target file is /bin/bash, replace it with an executable script with the specified interpreter path #!/proc/self/exe, and execute /proc/self/exe when executing /bin/bash in the container. Point to the runc file on the host. The attacker can then continue to write to /proc/self/exe to attempt to overwrite the runc file on the host. But generally, it won’t succeed because the kernel doesn’t allow it to be overwritten when running runc. To solve this problem, an attacker can use the O_PATH flag to open the file descriptor of /proc/self/exe, then reopen the file with /proc/self/fd/<nr> using the O_WRONLY flag and try to get from one in a loop. A separate process writes to this file. Overwriting will succeed when runc exits, after which runc can be used to attack other containers or hosts.
Security researchers have attached the relevant patch which fixes this issue. This patch is based on HEAD, but the code in libcontainer/nsenter/ changes so infrequently that it should apply cleanly to any old version of the runc codebase you are dealing with.