The Mapping Moved but the Cache Stayed: Vghost, the AI-Found vhost Flaw With a Root Exploit and a VM Escape
CVE-2026-74580, dubbed Vghost, is a memory-corruption flaw in the Linux kernel’s vhost virtualization-acceleration subsystem. The NVD record — published 21 August 2026, modified 14 October 2026, status Received, CNA kernel.org — scores it CVSS 8.8 (AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H). The upstream fix, commit de845981da67, landed 3 August 2026. Tencent Zhuque Lab published the full write-up on 12 October, with working demonstrations of both exploitation paths: unprivileged host users escalating to root, and an untrusted guest breaking out to affect the host.
The detail that earns this a briefing rather than a bulletin entry is in the write-up’s first paragraph: the flaw was discovered by Corvus AI in 2 hours, with Tencent Hunyuan’s Hy4-preview integrated into the subsequent exploit-verification and patch-validation loop. A decade-spanning kernel memory-safety bug, found by a machine in an afternoon, with demos for both sides of the virtualization boundary.
What the code does
We read the NVD description and the Zhuque Lab write-up rather than re-deriving the bug, and the mechanism is stated plainly. Each vhost virtual queue caches the IOTLB mapping that backs its vring metadata regions (descriptor, available, and used rings) in vq->meta_iotlb[]. The access check short-circuits on a cache hit:
if (vhost_vq_meta_fetch(vq, addr, len, type))
return true;
and the fetch itself performs no range check — it translates the address through the cached mapping arithmetically, which is only meaningful while the address is still inside that mapping. The cache is reset on IOTLB updates, invalidations, device-IOTLB initialisation, and queue reset — but not by VHOST_SET_VRING_ADDR or VHOST_SET_VRING_NUM. With a device IOTLB attached, those ioctls are accepted on a live queue and deliberately defer address validation to prefetch time. Once the cache is populated, that deferred validation never runs: the prefetch hits the stale entry and returns true, and every subsequent translation goes through the old mapping. The translated pointer bottoms out in raw copy routines that perform no access check of their own, so the access lands exactly where the stale translation says.
The write-up’s central observation is that the bug is the composition of two commits that are each individually reasonable: f88949138058 (v4.11, February 2017), which added the cache and the early return, and 0210a8db2aec (v5.9, October 2020), which moved guest-address validation out of the ioctl path and into prefetch. The second commit removed the ioctl-time check on the reconfiguration path while the first commit’s cache keeps the prefetch-time check from ever running. Neither change is wrong on its own; together they leave a window in which reconfiguration is neither checked eagerly nor lazily. The defect therefore spans, per the write-up, nearly a decade of releases from Linux 4.11 through 7.2, across distributions including Ubuntu, RHEL, Amazon Linux, Azure Linux, and Oracle Linux.
Two primitives from one stale entry
The stale cache covers the descriptor, available, and used rings alike, so the single bug yields two independent primitives on the same primed device. Re-pointing the used ring between kicks gives an arbitrary write: one completed descriptor makes vhost store an 8-byte used-ring entry — two attacker-chosen bytes followed by six zeroes — and each re-pointing places the next store at an arbitrary address, with byte alignment the attacker also controls. Re-pointing the descriptor-ring address instead gives an 8-byte arbitrary kernel read: the target’s first eight bytes are treated as a data-buffer address, miss the IOTLB, and come back to userspace inside the resulting IOTLB-miss message.
The read primitive disposes of KASLR without theatrics. It recovers the slide from gate 0 of the IDT, which lives at a fixed CPU entry-area address, reconstructs the divide-error handler from the gate’s offset fields, and subtracts the link-time symbol. The write-up is explicit that the host exploit is deterministic and race-free, needs no heap grooming, and depends on no kernel-structure layout — the three properties that separate a reliable privilege-escalation path from a research curiosity. The affected frontends are vhost-net and vhost-vsock: the fast path for guest networking and guest-host communication, i.e. the code that runs on nearly every KVM host that cares about performance.
The second vector is the one that matters to anyone running untrusted workloads in guests. In a virtualized environment with a virtual IOMMU, an untrusted guest can trigger the same stale-cache condition via VIRTIO_F_RING_RESET, inducing the host kernel to write out of bounds into the host QEMU process heap. The lab frames this deliberately against its own prior work: it previously published SCTPhantom, which demonstrated a container-escape vector, and presents Vghost as the virtual-machine-escape companion — a reminder, in its words, that trusted isolation boundaries may need to be reconsidered.
Why this belongs on an agent-security site
The VM boundary is load-bearing infrastructure for agent sandboxes. The dominant pattern for confining model-chosen code — run it in a VM, or in a container inside a VM — assumes the hypervisor’s host-side data path treats guest-influenced state as hostile. Vghost is a case where the host kernel cached a proof of validation and then kept accepting it after the thing it proved had changed. That shape should look familiar: it is the same family as the Podman checkpoint-annotation bypass, where flags were not evaluated and rejected but skipped entirely because the code path that evaluates them never ran. A control downstream of an early return — or behind a cache hit — is not weak. It is absent.
The discovery story is the other half of the briefing. Corvus AI finding this in two hours sits inside a pattern this site has been tracking all month: AI-assisted auditing operating at a scale where the scarce resource is no longer finding the bug but getting it fixed. The nineteen-second eighteen-CVE batch made that point for shell injection in JavaScript and Python helpers; the Podman record’s credit line — a consultancy using Claude models — made it for sandbox logic. Vghost extends the pattern into the kernel itself, and notably into the full loop: the write-up says the model was integrated not just into discovery but into exploit verification and patch validation. Credit the humans for the triage, the severity argument, and the demos; but the two-hour figure is the number to remember, because it reprices how long a bug like this gets to sit once capable finders are pointed at the tree. This one sat for nine years. The next one in this subsystem will not get nine years.
One honest qualification, in the spirit this site tries to keep: the record’s scope-change scoring (S:C with full host impact) describes the worst case faithfully — a guest escaping to the host QEMU process — but the realistic host-side path still requires local access to the vhost device nodes, and the guest-side path requires a virtual IOMMU configuration. Read the vector as the ceiling, and your own deployment — who can reach /dev/vhost-*, whether guests are untrusted, whether the vIOMMU is even enabled — as the floor.
What to do
- Upgrade to a kernel containing the fix. Upstream commit
de845981da67(“vhost: reset the vring metadata cache on vring reconfiguration”) is the fix; the NVD references list the stable-tree backports, so take your distribution’s patched kernel — Ubuntu, RHEL, Amazon Linux, Azure Linux, and Oracle Linux are all named as impacted. Anything in the 4.11-through-7.2 window without the backport is exposed. - Treat the vhost device nodes as a privilege boundary in your threat model. Local access plus this bug was root, deterministically. Restrict who can open the vhost devices, and audit which service accounts and containers hold those permissions — a container with device access and this bug skips several rungs of your escalation ladder.
- If you host untrusted guests, patch the host first and the guests never. The guest-to-host vector runs from inside the VM outward; guest kernels cannot mitigate it. Your patch priority is the hypervisor fleet, KVM hosts, and any CI or sandbox infrastructure that runs tenant code in guests with a virtual IOMMU.
- Reprice your auditing assumptions. A nine-year-old cache-invalidation gap in a hot, reviewed subsystem fell in two hours to an automated finder with a verification loop. If your “unlikely to be found” reasoning underwrites any control, retire it.
Verification note: the CVE identifier, NVD publication (21 August 2026) and modification (14 October 2026) timestamps, CVSS 3.1 vector and base score, Received status, and kernel.org CNA attribution were read first-hand from the NVD 2.0 API. The fix commit hash, its 3 August 2026 date, and its message were read first-hand from the GitHub API on the torvalds/linux mirror. The mechanism, affected kernel range (4.11 through 7.2), affected distributions and frontends, the two-hour Corvus AI discovery claim, the Hunyuan Hy4-preview verification-loop claim, the two composing commits, the exploitation primitives, the KASLR technique, the VIRTIO_F_RING_RESET guest vector, and the SCTPhantom reference are as stated in the Tencent Zhuque Lab write-up, fetched directly on 14 October 2026 — we did not independently reproduce the exploit, build a kernel, or test any distribution. Brave Search surfaced the write-up plus secondary coverage (The Hacker News, CybersecurityNews, SecurityOnline); all technical claims above trace to the write-up and the NVD record, not to aggregators.
Sources:
- Tencent Zhuque Lab — Vghost: Beyond the Privilege Boundary (12 October 2026, CVE-2026-74580 write-up with both exploitation demos)
- NVD — CVE-2026-74580 (published 21 August 2026, modified 14 October 2026, CVSS 3.1 8.8, status Received, kernel.org CNA)
- Upstream fix — de845981da67, “vhost: reset the vring metadata cache on vring reconfiguration” (3 August 2026)