A process inside a container, holding nothing more than CAP_MKNOD, ran mknod twice, walked a filesystem with debugfs, and overwrote a single binary on a guest microVM's "read-only" root filesystem. Fifteen minutes later, a systemd timer executed that binary as root. No kernel exploit. No race condition. No privileged container flag. Just two device nodes and an understanding of where the target file lived on disk.
That's CVE-2026-24834, disclosed February 19, 2026, CVSS 9.3. It hits Kata Containers — the runtime that gives every pod its own Linux kernel inside a KVM microVM specifically so a compromised container can't reach the host or its neighbors. The bug doesn't break KVM. It doesn't need to. It breaks the one assumption everything else was built on: that the guest's root filesystem was actually read-only.
The proof-of-concept (credited to researcher kostya-oai, patched by Kata maintainer sprt) didn't need a mount namespace escape or a privileged flag either — debugfs was enough to compute the exact partition start sector, sector size, and block offset of /usr/bin/systemd-tmpfiles without ever mounting the filesystem. Once the attacker knows the byte offset, a raw write to /dev/pmem0 lands directly on that binary. The only reason it takes fifteen minutes to pay off is that's how long it takes for a stock systemd timer unit to fire and execute the now-poisoned binary as root inside the guest. Swap the target binary and the wait time changes; the technique doesn't.
Are you exposed? The 90-second check
Before the mechanics, the thing you're here for. Run these three checks against any fleet running Kata in production for tenant or sandbox isolation:
1. Version. Anything before 3.27.0 is vulnerable if it uses Cloud Hypervisor.
kata-runtime version
# or, if you're on the v2 shim:
containerd-shim-kata-v2 --version2. Rootfs driver. Check what each Cloud Hypervisor configuration.toml actually mounts the guest rootfs with:
grep -A2 '\[hypervisor.clh\]' /opt/kata/share/defaults/kata-containers/configuration-clh.toml | grep disable_image_nvdimmdisable_image_nvdimm = false (or unset, pre-3.27.0's default) means the guest image is plugged via NVDIMM/virtio-pmem — that node is exploitable. disable_image_nvdimm = true forces virtio-block instead, which is what 3.27.0 ships by default.
3. Blast radius. Find out which RuntimeClasses actually route to Cloud Hypervisor, and which node pools they land on:
kubectl get runtimeclass -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.handler}{"\n"}{end}' | grep clhEvery workload scheduled under one of those RuntimeClasses inherited this exposure until the patch landed — that's your actual tenant count at risk, not a hypothetical.
If step 1 comes back below 3.27.0 and step 2 shows virtio-pmem, patch now. The rest of this post is why, and what to do if you can't patch immediately.
Why "read-only" wasn't: the virtio-pmem/DAX root cause
Kata's Cloud Hypervisor configuration shipped virtio-pmem as the default rootfs driver before 3.27.0 — a choice made for boot speed, not security, and the one config default the whole vulnerability traces back to.
Persistent-memory devices exist to skip the usual storage stack. Instead of the guest kernel issuing block I/O that a device driver translates into reads and writes the hypervisor can see and mediate, virtio-pmem uses DAX (Direct Access) to map the backing file straight into the guest's physical address space. The guest reads and writes memory directly. That's the entire point — it's fast because the hypervisor is out of the path.
Cloud Hypervisor tried to make this safe by opening the backing file read-only and mapping it MAP_PRIVATE with discard_writes=on: any write becomes copy-on-write, so it never reaches the file on the host's disk. But copy-on-write still means the write succeeds in guest memory. The Linux virtio-pmem driver never sets a read-only flag on the resulting block device — nothing in the guest actually enforces immutability. And because DAX means the hypervisor never sees individual reads or writes in the first place, there's no interception point where anyone could reject the write even if they wanted to.
So the guest kernel — the exact thing this whole architecture exists to not trust — was the only thing standing between "read-only rootfs" and an attacker with mknod. It had no chance to enforce anything, because it was never asked.
Cloud Hypervisor vs. QEMU vs. Firecracker: the full scope
The advisory is specific about Cloud Hypervisor, and specific about why the two other VMMs Kata supports are a different story — not identically safe, in two different ways:
| VMM | Rootfs mechanism | Status | Why |
|---|---|---|---|
| Cloud Hypervisor | virtio-pmem + DAX (pre-3.27.0 default) | Vulnerable | No read-only enforcement anywhere in the write path |
| QEMU (x86) | NVDIMM | Not exploitable | QEMU's x86 NVDIMM implementation enforces read-only mode at the VMM level — the same DAX performance trick, but with the hypervisor actually checking |
| QEMU (arm64) | NVDIMM | Unresolved caveat | The advisory itself notes arm64 QEMU lacks NVDIMM read-only support and states it's "believed" a guest write could reach the image file — flagged, not ruled out, not confirmed exploited |
| Firecracker | Not addressed | Unverified | The advisory doesn't scope Kata's Firecracker integration at all. Absence of a finding isn't a clearance — audit it yourself rather than assume it |
The fix for Cloud Hypervisor was to switch the rootfs driver from virtio-pmem to virtio-blk-pci — a conventional virtio block device where every I/O operation is a message to the hypervisor, which can enforce read-only access the way it was always supposed to. It's slower than DAX. That's the trade a correctly-configured system makes.
If you can't patch today: the entire exploit chain runs through one capability. Restrict CAP_MKNOD at the pod security policy or seccomp profile level for any workload on a Cloud Hypervisor RuntimeClass, and you've closed the only door the proof-of-concept walks through — without touching the VMM config. That's a stopgap, not a fix; get to 3.27.0 regardless.
There's also a second stopgap if you're stuck on an older Kata build for other reasons: force the same driver switch 3.27.0 makes its new default, directly in configuration-clh.toml, before you can complete a full upgrade.
[hypervisor.clh]
disable_image_nvdimm = trueThis forces the guest rootfs onto virtio-block instead of NVDIMM/virtio-pmem on whatever Kata version you're currently running. It costs the boot-time advantage DAX was buying you, but it closes the write path immediately, without waiting on a full upgrade cycle.
The harder lesson: hardware isolation is still a software decision
We've written before about why Kata's hardware boundary — a real guest kernel behind KVM's page tables — is the stronger guarantee against a genuinely adversarial tenant, versus gVisor's userspace syscall interception. That argument hasn't changed. A KVM escape is still a fundamentally harder problem than a Sentry escape, and CVE-2026-24834 never touched KVM at all — it's scoped as container-to-guest, not guest-to-host.
But "the boundary is hardware" was never a property of Kata as a name. It's a property of a specific configuration: which VMM, which rootfs driver, which version. Every one of those is a software decision made in a configuration.toml, and every one of them can quietly regress the exact guarantee a team picked Kata to get. DAX-backed rootfs is a legitimate, common performance optimization — it's also, it turns out, one that requires the guest kernel to behave, in a system whose entire premise is not requiring that.
The operational takeaway isn't "don't use Cloud Hypervisor." It's that a hardware isolation boundary bought once isn't a boundary kept forever — it needs the same patch-cadence discipline as any other security-critical dependency in the stack: know your version, know your VMM config, know which tenants actually sit behind it, and re-run that check on every Kata upgrade cycle, not just after a CVE makes you.
That discipline matters more, not less, as more of what runs inside these sandboxes is an AI agent's own tool calls rather than a human-reviewed deployment. An agent executing arbitrary shell commands on behalf of a user is exactly the "genuinely untrusted, adversarial-by-design" tier that justified reaching for Kata over gVisor in the first place — and it's also a workload shape that will happily discover CAP_MKNOD is still available in a default pod spec long before a human operator notices. The fix isn't more trust in the sandbox; it's less trust in any single layer of it, hardware boundary included.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. If you're operating Kata (or any sandboxed runtime) for tenant isolation, that only works if you can actually see which VMM and version every node is running. Star the repo on GitHub or deploy your first app today.



