Breakdown of New RunC vulnerabilities CVE-2025-31133, CVE-2025-52565, and CVE‑2025‑52881
I recommend reading the actual exploit https://seclists.org/oss-sec/2025/q4/161. It’s mind-blowing, how complex and how many jumps it takes actually to do something like this:
What’s even happening?
Essentially, an attacker wants to gain elevated access on the machine, but is only an unprivileged user. This vulnerability allows the attacker to obtain root on host , crash the kernel, and disable Linux Security Module policies. In a nutshell, pretty bad stuff.
The root of it all
Essentially, the root cause of all three of these vulnerabilities is a Time-of-Check to Time-of-Use (TOCTU) vulnerability in runc’s mounting logic.
runc just wants to mount normal directories into a container, but an attacker can sabotage this process, to make runc mount some protected directories into the container, the most useful of them being /proc/* dirs.
Attackers want to do this, because as an unprivileged process, they can’t access these protected knobs to control the whole machine, and the kernel.
The attack is quite simple, runc opens a file/dir/mount validates the path, and then performs the mount. In this small time window between mount and read, the attacker is replacing a path with a symlink during a race window, so that runc mounts the attacker’s target instead.
All three CVEs follow this pattern, just in different places in runc.
Attacking masking paths: CVE-2025-31133
Typically, runc masks specific directories, so that sensitive paths are not exposed to containers. It does this by mounting /dev/null over those paths.
What an attacker can do is use that TOCTU attack to make runc mount a sensitive directory instead of /dev/null. In the CVE, the examples directories were /proc/sys/kernel/core_pattern and /proc/sysrq-trigger
Both of these are really, really bad, essentially game-over scenarios, if mounted in the container.
Mounting /proc/sys/kernel/core_pattern
If the attacker chose /proc/sys/kernel/core_pattern, they could basically run any arbitrary code they wanted on the system as root.
This is because core_pattern runs whenever a program crashes. And if an attacker has access to core_pattern, they can configure its path/arguments to run whatever bad script they want. They can also prefix core_pattern with a |, which effectively allows their command to run as a root-level process within the host’s namespace.
So an attacker can write any script they want to core_pattern, prefix it with |, and essentially run it across the whole system as root, doing whatever they want.
Mounting /proc/sysrq-trigger
If they have access to /proc/sysrq-trigger, they can essentially control sysrq, which allows you to perform low-level kernel actions immediately.
You could cause the kernel to panic, shut down processes, and do a lot of bad things.
Attacking the console: CVE-2025-52565
This is very similar to the masking attack; runc needs to give the container a console, so it mounts /dev/pts/$N to /dev/console. Now, an attacker can symlink /dev/pts/$N to a protected dir like core_pattern or sysrq-trigger, so we can write to the console and thereby write to these protected dirs.
Disable Linux Security Module (LSM) polices: CVE‑2025‑52881
When runc needs to write an LSM policy, it needs to write it to /proc/self/attr/* to set LSM labels for the container that is being started. An attacker can execute a very similar TOCTU attack on this write operation.
runc wants to open /proc/self/attr/*, but during that small time window, if an attacker symlinks the file to another location, the LSM labels are not written, so security policies are not enforced. What could be even worse is that those writes could be piped to other sensitive files, such as core_pattern or sysrq-trigger.
Caveats
This is harder for the attacker to execute, since they must be able to symlink the file where the LSM policy attribute path is stored. This also does not affect something like BPF-LSM, since this is only a way for userspace applications to write policies to the kernel.
How can we stop this?
Upgrade to the patched versions of runc as soon as possible, which are versions 1.2.8, 1.3.3, 1.4.0-rc.3. This should remove the immediate threat vector.
As for more proactive steps to take against a similar attack, you could:
Run most workloads as rootless. It
may take extra effort in some cases, but it immediately improves your security posture.
Another significant step we could take is to prevent symlink creation in specific directories.
If we can forbid symlinks on proc/sys and /proc/*/attr/*, you should be able to prevent anyone from directly symlinking to one of these protected dirs, even if a root process (like runc!) is compromised.
To enforce something like this, using something like BPF-LSM, it should be pretty easy to implement policy by writing a hook on something like security_inode_symlink and security_file_open (I don’t have much experience with AppArmor and SELinux, so they may not work, since they rely on LSM labels on files, unlike BPF-LSM, which doesn’t rely on that)
PS: Bomfather can stop this, we aren’t trying to plug ourselves, so use whatever works for you best :)

