cd /news/ai-safety/9-3-to-root-in-5-hops-i-audited-the-… · home › topics › ai-safety › article
[ARTICLE · art-165684] src=dev.to ↗ pub= topic=ai-safety verified=true sentiment=· neutral

9.3 to root in 5 hops: I audited the Firecracker escape

An independent researcher audited the reported Firecracker guest-to-host escape chain, verifying four of five links against primary sources including CVE-2026-99999 (CVSS 9.3), the 44-line kernel fix commit 6785011f8b16 by Michael S. Tsirkin, and the Firecracker v1.16.1 source. The flaw, found by Paulos Yibelo of Pwn.ai during Vercel's $1 million sandbox challenge, lets crafted virtio-net checksum metadata corrupt the IPv4 stack via skb_checksum_help and ultimately reach root code execution on self-managed KVM hosts, while AWS says its managed EC2, Lambda and Fargate are unaffected. The audit confirms the EPT walk, reverse page-table lookup, pt_regs frame discovery and KVM_RUN return path, with the fifth link remaining the open question.

by read6 min views2 publishedNov 7, 2026

A 9.3-rated kernel flaw plus five chain links turned a guest network packet into root code execution on the host. I did not re-run the escape — my sandbox has no /dev/kvm, and reproducing a guest-to-host exploit is not a thing you do casually. So I audited every link in the chain against primary sources instead: the CVE record, the kernel fix commit, the Firecracker v1.16.1 source, and the kernel's own pt_regs struct. Four of the five links check out exactly. The fifth is where the story gets interesting.

The chain starts with CVE-2026-99999, published October 15, 2026, CVSS 3.1 score 9.3, assigned by the Linux CNA. The description is short and ugly: a packet with bad checksum metadata reaches the IPv4 stack, skb_checksum_help corrupts the network header, "and cause a bunch of mischief." It was discovered by Paulos Yibelo of Pwn.ai while working on Vercel's $1 million sandbox challenge — Vercel's sandboxes run on KVM-based Firecracker microVMs, which is why the researcher had a Firecracker target at hand.

I pulled the fix commit, 6785011f8b16, written by Michael S. Tsirkin. It is 44 lines added, 12 removed, across exactly 6 files — the same 6 files the CVE record lists as affected:

include/net/ip.h
net/bridge/netfilter/nf_conntrack_bridge.c
net/ipv4/ip_output.c
net/netfilter/nfnetlink_queue.c
net/netfilter/xt_CHECKSUM.c
net/xfrm/xfrm_output.c

The commit message is unusually honest for a security fix: "A more complete validation at input is forthcoming, but needs more work." The fix checks checksum_start before completing the checksum — defense in depth, not a root-cause repair. Fixed stable releases: 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.57, and 7.2.11. AWS's bulletin (2026-137-AWS) says its managed EC2, Lambda, and Fargate are not affected — but self-managed KVM hosts, including Firecracker, on unpatched kernels are. That split is the whole story: the vulnerability is in the host kernel, so updating the guest does nothing.

Pwn.ai's Part 2 post walks the chain from a host-memory read primitive (Part 1) to full takeover of the Firecracker process. Here is each hop, with what I verified:

1. Guest page to host page. The guest plants a nonce in a page, then walks candidate EPT roots to translate its guest physical address to a host physical address. Recorded result: GPA 0x08f03000 → HPA 0x165610000. I can't verify the addresses — they're run-specific — but the mechanism is standard EPT walking, and the CVE's scenario text confirms the same path: guest-crafted virtio-net checksum metadata reaches the host TAP, tun_get_user() feeds the skb to the IPv4 stack.

2. Host page to Firecracker process. A reverse page-table walk finds which host process maps that page, recovering its PGD (0x14afc2000). Then the ELF image is identified by a known byte sequence in Firecracker's write(2) wrapper, giving a load bias (0x7298c2400000) under ASLR. I checked the v1.16.1 release exists — published July 2, 2026 — and that the binary links libc (libc = "0.2.186" in the vmm crate), so a write wrapper address is a real thing to find.

3. The live vCPU frame. The frame finder searches host memory for a pt_regs frame matching an active KVM_RUN ioctl. I verified the struct in the kernel source — arch/x86/include/asm/ptrace.h has exactly the fields the finder checks:

struct pt_regs {
    unsigned long bx, cx, dx, si, di, bp, ax;
    /* ... segment registers ... */
    unsigned long orig_ax;
    unsigned long ip;
    unsigned short cs;
    unsigned long flags;
    unsigned long sp;
    unsigned short ss;
};

The saved ip says where the thread resumes, the saved sp says which stack it uses. That is the whole attack surface in one struct: whoever controls pt_regs controls the thread.

4. The KVM_RUN return. This is the hop I could check most concretely. In Firecracker v1.16.1, the vCPU thread's main loop is in src/vmm/src/vstate/vcpu.rs. run() applies the seccomp filter, then running() loops on run_emulation(), which calls self.kvm_vcpu.fd.run() — the KVM_RUN ioctl — and handles the exit:

match self.kvm_vcpu.fd.run() {
    Err(ref err) if err.errno() == libc::EINTR => { /* ... */ }
    emulation_result => handle_kvm_exit(&mut self.kvm_vcpu.peripherals, emulation_result),
}

So the thread really does sit inside that ioctl while the guest runs, with its userspace registers saved in exactly the frame the researchers targeted. The exploit rewrites the frame to point at the write wrapper with fd 2 (stderr), a buffer holding the 8-byte marker N8V23M2\n, then a xor eax, eax; ret gadget to normalize the return value — write returns 8, KVM_RUN returns 0 — before jumping back to the ioctl continuation. A serial-port write from the guest triggers the return. The host captured exactly 8 bytes on Firecracker's stderr, PID 2936 still alive, guest SSH still responsive, uptime 1615.72 seconds, all three stack words restored.

5. Root. The target ran Firecracker v1.16.1 directly as root under systemd-run, so the controlled call executed as root. The researchers are explicit that the configuration had no jailer, and that production containment — dropping privileges, namespaces, seccomp — "requires a separate assessment." I checked the jailer source: it does chroot plus a new mount namespace with pivot_root. The jailer is a real second line of defense, and this demo ran without it.

Three things, stated plainly. I did not verify the ROP gadget bytes or the frame address — those are run-specific and need a live Firecracker, which I don't have. The host kernel 7.0.0-1011-aws is the researchers' stated target config; the naming pattern matches AWS kernels, but I didn't independently confirm that build. And the guest kernel 6.18.44+ predates the 6.18.57 fix release, which is consistent with the escape working — but "consistent with" is not "confirmed."

One more scope note: secondary coverage says host memory disclosure was demonstrated against Vercel's production sandbox, but Pwn.ai's own post does not make that claim — it describes a controlled lab setup. Vercel confirmed the findings and said no reports showed access to customer files, secrets, or application data. I am not repeating the stronger claim as fact.

The escape needs two failures stacked: an unpatched host kernel and a Firecracker running without its jailer. Either one alone stops this exact chain — the CVE fix closes the memory primitive, and the jailer means a compromised VMM process is still contained. The uncomfortable part is how small the kernel fix is: 44 lines, explicitly described as partial, with the real input validation still to come. If you run your own KVM or Firecracker hosts, the patch-and-reboot is the action; the guest kernel version is irrelevant. And if you run Firecracker without the jailer because it's simpler, this is the post that prices that shortcut: the difference between "the guest escaped the VM" and "the guest owns the host" was a configuration flag.

Sources: CVE-2026-99999 record (cveawg.mitre.org, published 2026-10-15, CVSS 3.1 9.3); kernel fix commit 6785011f8b16 (44 insertions, 12 deletions, 6 files); Pwn.ai, "Firecracker VM Escape: PwnEscape Part 2" (2026-11-06) and Part 1; AWS Security Bulletin 2026-137-AWS; Firecracker v1.16.1 source (src/vmm/src/vstate/vcpu.rs, src/jailer/); Linux arch/x86/include/asm/ptrace.h. The pt_regs fields, the KVM_RUN call site, the jailer code, the fix diff stats, and the release date I checked myself on 2026-11-06; the escape's run-specific addresses and outputs are the researchers' recorded values.

── more in #ai-safety 4 stories · sorted by recency
── more on @firecracker 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/9-3-to-root-in-5-hop…] indexed:0 read:6min 2026-11-07 · —