CVE-2024-21626
runc Container Escape — Leaky Vessels
Impact: A file descriptor leak in runc < 1.1.12 allows a container process to access the host filesystem via /proc/self/fd, escaping container isolation and gaining root access to the host. Affects all runc-based runtimes: Docker, Kubernetes (containerd), Podman.
Affected Version Matrix
| Component | Vulnerable | Fixed |
|---|---|---|
| runc | < 1.1.12 | 1.1.12+ |
| Docker Engine | < 25.0.2 / < 24.0.9 | 25.0.2+ / 24.0.9+ |
| containerd | < 1.7.13 / < 1.6.27 | 1.7.13+ / 1.6.27+ |
| Kubernetes (node) | All versions using vulnerable runc | Update node container runtime |
| Podman | Versions using runc < 1.1.12 | Update runc or use crun |
Step-by-Step Fix Runbook
# runc version runc --version # Vulnerable: runc < 1.1.12 # Docker version docker version | grep -i version # Vulnerable Docker: < 25.0.2 or < 24.0.9 # containerd version containerd --version # Vulnerable containerd: < 1.7.13 or < 1.6.27 # Kubernetes node runtime kubectl get nodes -o wide # Check container runtime version
# Ubuntu/Debian — update Docker Engine (includes runc) apt-get update apt-get install --only-upgrade docker-ce docker-ce-cli containerd.io systemctl restart docker # Verify patched versions runc --version # Must be 1.1.12+ docker version # Must be 25.0.2+ or 24.0.9+ containerd --version # Must be 1.7.13+ or 1.6.27+ # Kubernetes — update node container runtime # Follow your distribution's node update process # Then drain and uncordon each node: kubectl drain <node> --ignore-daemonsets # (update runtime on node) kubectl uncordon <node>
# Run containers with hardened flags — reduces blast radius
docker run \
--read-only \
--cap-drop=ALL \
--no-new-privileges \
--user=65534 \
--security-opt=no-new-privileges:true \
--security-opt seccomp=/etc/docker/seccomp-default.json \
myimage
# Kubernetes PodSecurityContext equivalent:
securityContext:
runAsNonRoot: true
runAsUser: 65534
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]# Rootless Docker — containers cannot escape to root on host dockerd-rootless-setuptool.sh install # Or use Podman in rootless mode (rootless by default) podman run --rm myimage # Rootless containers: even if container escape succeeds, # the attacker only gets the user's UID on the host — not root
# Docker — apply default Seccomp profile (should be automatic) docker info | grep -i seccomp # Apply custom restrictive Seccomp profile docker run --security-opt seccomp=/etc/docker/seccomp-default.json myimage # Enable AppArmor profile for Docker containers docker run --security-opt apparmor=docker-default myimage # Kubernetes — enforce PodSecurityAdmission # namespace label for restricted policy: kubectl label namespace production pod-security.kubernetes.io/enforce=restricted
# Check for unexpected processes running as host root from container context
ps aux | grep -E "docker|runc|containerd" | grep root
# Audit container escape indicators:
# - Container process accessing /proc/self/fd paths outside container
# - Unexpected bind mounts to host paths
# - New files in host root filesystem from container UID
# Enable Docker audit logging
cat /etc/docker/daemon.json
# Add: "log-driver": "json-file", "log-opts": {"max-size": "10m"}
# Monitor with auditd
auditctl -w /proc/self/fd -p rwxa -k container-escape-attemptFrequently Asked Questions
What is the Leaky Vessels vulnerability?
Leaky Vessels is the name given to a group of container escape vulnerabilities disclosed in January 2024, including CVE-2024-21626 (runc), CVE-2024-23651, CVE-2024-23652, and CVE-2024-23653 (BuildKit). CVE-2024-21626 is the most critical: a file descriptor leak in runc allows a process inside a container to access the host's filesystem via /proc/self/fd, enabling full container escape to root on the host.
How does the runc file descriptor leak work?
runc uses /proc/self/fd to manage container filesystem mounts. Due to a timing issue in how runc handles file descriptors during container setup, a file descriptor pointing to the host's working directory can remain open and accessible inside the container. By using the WORKDIR instruction in a Dockerfile or a crafted container, an attacker can access /proc/self/fd/<fd> to traverse to host paths — effectively escaping the container namespace.
Is Kubernetes affected by CVE-2024-21626?
Yes. Kubernetes uses runc as the default container runtime via containerd. Any Kubernetes cluster running containerd < 1.7.13 or < 1.6.27 (which includes runc < 1.1.12) is vulnerable. A malicious container workload (e.g., a compromised pod) could exploit this to escape to the host node with root privileges, potentially compromising the entire node and pivoting to other cluster resources.
Does running as non-root mitigate CVE-2024-21626?
Partially. Running as non-root reduces the impact of a successful escape — the attacker gets the container's UID on the host rather than root. However, the file descriptor leak itself is not prevented by the user ID. The only complete mitigation is patching runc to 1.1.12+. Running as non-root, with --cap-drop=ALL and a restrictive Seccomp profile, is essential defense-in-depth but not a substitute for the patch.