VYPR
High severityGHSA Advisory· Published May 27, 2026· Updated May 27, 2026

Kata guest escape: runtime-rs guest-root to host-root escape via virtiofs

CVE-2026-47243

Description

Summary

In the runtime-rs standalone virtio-fs path, verified here with QEMU (and verified with Cloud Hypervisor too), Kata Containers runs host virtiofsd as root with:

--sandbox none --seccomp none

If an attacker has root-equivalent execution inside the Kata guest VM, they can send raw FUSE requests directly to the host virtiofsd. With the tested runtime-rs virtio-fs configuration, a raw FUSE_SYMLINK request whose new symlink name is an absolute host path is honored outside the virtio-fs shared directory.

This lets guest root create host-root owned symlinks in sensitive host paths. The PoC created here will create symlinks in the host /etc/cron.d directory, causing host cron to execute a guest-controlled payload as host root.

Impact: guest root can execute code as host root.

Affected configuration

The verified host used:

/opt/kata/share/defaults/kata-containers/runtime-rs/configuration-qemu-runtime-rs.toml

rootless = false
shared_fs = "virtio-fs"
virtio_fs_daemon = "/opt/kata/libexec/virtiofsd"
hypervisor_name = "qemu"
debug_console_enabled = false

Pinned upstream references, using Kata Containers main commit 2ffd1538a296cff93a357bfba0dfca747480a1f8:

Details

The guest kernel normally owns the virtio-fs client. A normal guest process will use filesystem syscalls, and the guest kernel will validate the paths, and only then does the kernel send FUSE messages to the host backend.

An attacker with root-equivalent access inside the guest can bypass that guest virtio-fs client. They can access the virtio-fs PCI device, mmap the virtio PCI BAR, recover guest physical addresses from /proc/self/pagemap, and build their own virtqueue from userspace. That queue can submit attacker-built FUSE messages directly to host virtiofsd.

The relevant primitive is FUSE_SYMLINK. An attacker can send a request whose body contains:

new symlink name: /etc/cron.d/kata-go-escape-cron-
symlink target: /proc//root/run/kata-containers/shared/sandboxes//ro/passthrough//rootfs/tmp/kata-go-escape-payload

The new symlink name is an absolute host path. virtiofsd should reject that request or force it to resolve below the configured --shared-dir. In the tested runtime-rs path, host-root unsandboxed virtiofsd accepts the absolute name, creating a real host symlink under /etc/cron.d.

The attacker can make the symlink target resolve through /proc//root/... for a live Kata runtime process whose mount namespace can see the guest-created payload. One matching runtime PID is enough.

When the host cron reads /etc/cron.d, it follows the root-owned symlink, loads the guest-created crontab payload, and executes it as host root.

PoC

sudo timeout --foreground --kill-after=10s 600s ctr run --rm \
  --runtime /opt/kata/runtime-rs/bin/containerd-shim-kata-v2 \
  --runtime-config-path /opt/kata/share/defaults/kata-containers/runtime-rs/configuration-qemu-runtime-rs.toml \
  --privileged \
  --privileged-without-host-devices \
  docker.io/library/kata-go-escape:local \
  "$run_id"

The container is privileged only to model the post-escape condition where the attacker already has guest-root capabilities. It is not the vulnerability by itself.

Inside the guest, the PoC:

  1. Writes a cron payload to guest /tmp/kata-go-escape-payload.
  2. Finds the virtio-fs PCI device in guest /sys.
  3. Takes over a virtio-fs queue from userspace.
  4. Sends FUSE_INIT.
  5. Discovers the current runtime-rs sandbox under passthrough/.
  6. Looks up passthrough//rootfs/tmp/kata-go-escape-payload.
  7. Sends raw FUSE_SYMLINK requests where the new symlink names are absolute host paths under /etc/cron.d.
  8. Keeps the guest alive while host cron scans.

Example log lines:

[guest] virtio-fs PCI device: /sys/devices/pci0000:00/0000:00:05.0
[res] sandbox_id=kata-go-escape-test-1778522686-1539
[res] lookup_path_error=0 path=passthrough/kata-go-escape-test-1778522686-1539/rootfs/tmp/kata-go-escape-payload nodeid=21
[spray] pid=1 err=-2 created_candidates=1

err=-2 is expected for the symlink spray. virtiofsd can return ENOENT after the side effect because its follow-up lookup is still relative to the export root. The host symlink creation has already happened.

Impact

The PoC proves guest-root to host-root command execution.

Verified host proof:

/run/kata-go-escape.proof

uid=0(root) gid=0(root) groups=0(root)
Mon May 11 18:05:01 UTC 2026

The proof file is written in host /run by host cron. It is not written by the guest process and not written by virtiofsd.

An attacker who reaches guest root can therefore cross the Kata isolation boundary and execute commands as host root on affected runtime-rs virtio-fs deployments.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Guest root can escape to host root by sending a raw FUSE_SYMLINK request through an unsandboxed virtiofsd in Kata Containers runtime-rs.

Vulnerability

In the runtime-rs standalone virtio-fs path of Kata Containers (verified with QEMU and Cloud Hypervisor), the host virtiofsd is launched with --sandbox none --seccomp none and runs as root [1][2][3]. When the configuration uses shared_fs = "virtio-fs", rootless = false, and the default virtio_fs_daemon path, the guest VM's root-equivalent attacker can send arbitrary raw FUSE requests directly to the host virtiofsd because the guest kernel's normal path validation is bypassed. This affects Kata Containers versions prior to the fix in release 3.31.0 (commit ffa59ce) [1][4].

Exploitation

An attacker with root-equivalent access inside the Kata guest VM can craft a raw FUSE_SYMLINK request whose new symlink name is an absolute host path (e.g., /etc/cron.d/evil). The unsandboxed host virtiofsd honors this request outside the intended virtio-fs shared directory, creating a host-root owned symlink on the host filesystem. The provided proof-of-concept targets /etc/cron.d to trigger host cron execution of a guest-controlled payload [2][3].

Impact

Successful exploitation allows a guest root attacker to execute arbitrary code as host root. By creating a symlink in a host directory such as /etc/cron.d, the attacker can cause the host's cron daemon to run a payload with full host root privileges, resulting in a complete host compromise [2][3].

Mitigation

The vulnerability is fixed in Kata Containers release 3.31.0 (commit ffa59ce) [1][4]. The fix also adds a security warning about the virtio_fs_extra_args annotation in runtime-rs configuration, recommending that it not be enabled unless all annotation sources are fully trusted [4]. Users should upgrade to version 3.31.0 or later. No workaround is available for unaffected configurations (i.e., those not using the runtime-rs standalone virtio-fs path with --sandbox none --seccomp none).

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/kata-containers/kata-containersGo
< 0.0.0-20260519062212-ffa59ce3aa780.0.0-20260519062212-ffa59ce3aa78

Affected products

2

Patches

2
ffa59ce3aa78

Merge commit from fork

https://github.com/kata-containers/kata-containersFabiano FidêncioMay 19, 2026via ghsa-ref
4 files changed · +15 7
  • docs/how-to/how-to-set-sandbox-config-kata.md+4 2 modified
    @@ -49,9 +49,11 @@ Hypervisor annotations must be explicitly whitelisted in the Kata runtime config
     
     ```toml title="/path/to/configuration.toml"
     # List of valid annotation names for the hypervisor
    -enable_annotations = ["enable_iommu", "virtio_fs_extra_args", "kernel_params"]
    +enable_annotations = ["enable_iommu", "kernel_params"]
     ```
     
    +Warning: do not enable `virtio_fs_extra_args` in `enable_annotations` unless you fully trust all annotation sources. Passing arbitrary `virtiofsd` options can be abused for malicious host-side behavior.
    +
     | Key | Value Type | Comments |
     |-------| ----- | ----- |
     | `io.katacontainers.config.hypervisor.asset_hash_type` | string | the hash type used for assets verification, default is `sha512` |
    @@ -107,7 +109,7 @@ enable_annotations = ["enable_iommu", "virtio_fs_extra_args", "kernel_params"]
     | `io.katacontainers.config.hypervisor.virtio_fs_cache_size` | uint32 | virtio-fs DAX cache size in `MiB` |
     | `io.katacontainers.config.hypervisor.virtio_fs_cache` | string | the cache mode for virtio-fs, valid values are `always`, `auto` and `never` |
     | `io.katacontainers.config.hypervisor.virtio_fs_daemon` | string | virtio-fs `vhost-user` daemon path |
    -| `io.katacontainers.config.hypervisor.virtio_fs_extra_args` | string | extra options passed to `virtiofs` daemon |
    +| `io.katacontainers.config.hypervisor.virtio_fs_extra_args` | string | extra options passed to `virtiofs` daemon. **Security warning:** enabling this annotation can be abused for malicious host-side behavior |
     | `io.katacontainers.config.hypervisor.enable_guest_swap` | `boolean` | enable swap in the guest |
     | `io.katacontainers.config.hypervisor.use_legacy_serial` | `boolean` | uses legacy serial device for guest's console (QEMU) |
     | `io.katacontainers.config.hypervisor.default_gpus` | uint32 | the minimum number of GPUs required for the VM. Only used by remote hypervisor to help with instance selection |
    
  • docs/runtime-configuration.md+3 1 modified
    @@ -23,9 +23,11 @@ rootless = false
     # List of valid annotation names for the hypervisor
     # Each member of the list is a regular expression, which is the base name
     # of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path"
    -enable_annotations = ["enable_iommu", "virtio_fs_extra_args", "kernel_params"]
    +enable_annotations = ["enable_iommu", "kernel_params"]
     ```
     
    +Warning: do not enable `virtio_fs_extra_args` in `enable_annotations` unless you fully trust all annotation sources. Allowing pods to pass `virtiofsd` extra arguments can be abused to inject unsafe daemon options and lead to malicious host-side behavior.
    +
     These files should never be modified directly. If you wish to create a modified version of these files, you may create your own [custom runtime](helm-configuration.md#custom-runtimes). For example, to modify the image path, we provide these values to helm:
     
     ```yaml title="values.yaml"
    
  • src/runtime/Makefile+4 2 modified
    @@ -223,8 +223,10 @@ DEFMEMSLOTS := 10
     DEFMAXMEMSZ := 0
     #Default number of bridges
     DEFBRIDGES := 1
    -DEFENABLEANNOTATIONS := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\"]
    -DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
    +# Security note: do not enable "virtio_fs_extra_args" by default.
    +# Allowing pods to pass arbitrary virtiofsd arguments can be abused for malicious host-side behavior.
    +DEFENABLEANNOTATIONS := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\"]
    +DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
     DEFDISABLEGUESTSECCOMP := true
     DEFDISABLEGUESTEMPTYDIR := false
     DEFEMPTYDIRMODE := shared-fs
    
  • src/runtime-rs/Makefile+4 2 modified
    @@ -174,8 +174,10 @@ DEFMAXMEMSZ := 0
     DEFBRIDGES := 1
     ##VAR DEFNETQUEUES=<number> Default number of network queues
     DEFNETQUEUES := 1
    -DEFENABLEANNOTATIONS := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\"]
    -DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
    +# Security note: do not enable "virtio_fs_extra_args" by default.
    +# Allowing pods to pass arbitrary virtiofsd arguments can be abused for malicious host-side behavior.
    +DEFENABLEANNOTATIONS := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\"]
    +DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
     DEFDISABLEGUESTSECCOMP := true
     DEFDISABLEGUESTEMPTYDIR := false
     DEFEMPTYDIRMODE := shared-fs
    
ffa59ce3aa78

Merge commit from fork

https://github.com/kata-containers/kata-containersFabiano FidêncioMay 19, 2026via text-mined
4 files changed · +15 7
  • docs/how-to/how-to-set-sandbox-config-kata.md+4 2 modified
    @@ -49,9 +49,11 @@ Hypervisor annotations must be explicitly whitelisted in the Kata runtime config
     
     ```toml title="/path/to/configuration.toml"
     # List of valid annotation names for the hypervisor
    -enable_annotations = ["enable_iommu", "virtio_fs_extra_args", "kernel_params"]
    +enable_annotations = ["enable_iommu", "kernel_params"]
     ```
     
    +Warning: do not enable `virtio_fs_extra_args` in `enable_annotations` unless you fully trust all annotation sources. Passing arbitrary `virtiofsd` options can be abused for malicious host-side behavior.
    +
     | Key | Value Type | Comments |
     |-------| ----- | ----- |
     | `io.katacontainers.config.hypervisor.asset_hash_type` | string | the hash type used for assets verification, default is `sha512` |
    @@ -107,7 +109,7 @@ enable_annotations = ["enable_iommu", "virtio_fs_extra_args", "kernel_params"]
     | `io.katacontainers.config.hypervisor.virtio_fs_cache_size` | uint32 | virtio-fs DAX cache size in `MiB` |
     | `io.katacontainers.config.hypervisor.virtio_fs_cache` | string | the cache mode for virtio-fs, valid values are `always`, `auto` and `never` |
     | `io.katacontainers.config.hypervisor.virtio_fs_daemon` | string | virtio-fs `vhost-user` daemon path |
    -| `io.katacontainers.config.hypervisor.virtio_fs_extra_args` | string | extra options passed to `virtiofs` daemon |
    +| `io.katacontainers.config.hypervisor.virtio_fs_extra_args` | string | extra options passed to `virtiofs` daemon. **Security warning:** enabling this annotation can be abused for malicious host-side behavior |
     | `io.katacontainers.config.hypervisor.enable_guest_swap` | `boolean` | enable swap in the guest |
     | `io.katacontainers.config.hypervisor.use_legacy_serial` | `boolean` | uses legacy serial device for guest's console (QEMU) |
     | `io.katacontainers.config.hypervisor.default_gpus` | uint32 | the minimum number of GPUs required for the VM. Only used by remote hypervisor to help with instance selection |
    
  • docs/runtime-configuration.md+3 1 modified
    @@ -23,9 +23,11 @@ rootless = false
     # List of valid annotation names for the hypervisor
     # Each member of the list is a regular expression, which is the base name
     # of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path"
    -enable_annotations = ["enable_iommu", "virtio_fs_extra_args", "kernel_params"]
    +enable_annotations = ["enable_iommu", "kernel_params"]
     ```
     
    +Warning: do not enable `virtio_fs_extra_args` in `enable_annotations` unless you fully trust all annotation sources. Allowing pods to pass `virtiofsd` extra arguments can be abused to inject unsafe daemon options and lead to malicious host-side behavior.
    +
     These files should never be modified directly. If you wish to create a modified version of these files, you may create your own [custom runtime](helm-configuration.md#custom-runtimes). For example, to modify the image path, we provide these values to helm:
     
     ```yaml title="values.yaml"
    
  • src/runtime/Makefile+4 2 modified
    @@ -223,8 +223,10 @@ DEFMEMSLOTS := 10
     DEFMAXMEMSZ := 0
     #Default number of bridges
     DEFBRIDGES := 1
    -DEFENABLEANNOTATIONS := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\"]
    -DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
    +# Security note: do not enable "virtio_fs_extra_args" by default.
    +# Allowing pods to pass arbitrary virtiofsd arguments can be abused for malicious host-side behavior.
    +DEFENABLEANNOTATIONS := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\"]
    +DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
     DEFDISABLEGUESTSECCOMP := true
     DEFDISABLEGUESTEMPTYDIR := false
     DEFEMPTYDIRMODE := shared-fs
    
  • src/runtime-rs/Makefile+4 2 modified
    @@ -174,8 +174,10 @@ DEFMAXMEMSZ := 0
     DEFBRIDGES := 1
     ##VAR DEFNETQUEUES=<number> Default number of network queues
     DEFNETQUEUES := 1
    -DEFENABLEANNOTATIONS := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\"]
    -DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"virtio_fs_extra_args\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
    +# Security note: do not enable "virtio_fs_extra_args" by default.
    +# Allowing pods to pass arbitrary virtiofsd arguments can be abused for malicious host-side behavior.
    +DEFENABLEANNOTATIONS := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\"]
    +DEFENABLEANNOTATIONS_COCO := [\"enable_iommu\", \"kernel_params\", \"kernel_verity_params\", \"default_vcpus\", \"default_memory\", \"cc_init_data\"]
     DEFDISABLEGUESTSECCOMP := true
     DEFDISABLEGUESTEMPTYDIR := false
     DEFEMPTYDIRMODE := shared-fs
    

Vulnerability mechanics

Root cause

"virtiofsd, launched with --sandbox none --seccomp none, does not validate that the new symlink name in a FUSE_SYMLINK request stays within the configured shared directory, allowing an attacker inside the guest to create host-root-owned symlinks at arbitrary absolute host paths."

Attack vector

An attacker with root-equivalent execution inside the Kata guest VM bypasses the guest kernel's virtio-fs client by directly accessing the virtio-fs PCI device, mmapping the virtio PCI BAR, recovering guest physical addresses from /proc/self/pagemap, and building a userspace virtqueue [ref_id=1]. Through this queue the attacker submits a raw FUSE_SYMLINK request where the new symlink name is an absolute host path (e.g., /etc/cron.d/kata-go-escape-cron-&lt;pid&gt;) and the symlink target points through /proc/&lt;pid&gt;/root/... to a guest-controlled payload [ref_id=1]. Because virtiofsd runs as host root with --sandbox none --seccomp none, it honors the absolute path and creates a real host symlink outside the shared directory [ref_id=1]. Host cron then follows the symlink, loads the guest-created crontab payload, and executes it as host root [ref_id=1].

Affected code

The runtime-rs standalone virtio-fs path launches virtiofsd with --sandbox none --seccomp none in src/runtime-rs/crates/resource/src/share_fs/share_virtio_fs_standalone.rs (lines 82-92) [ref_id=1]. The runtime-rs configuration template (configuration-qemu-runtime-rs.toml.in) sets rootless = false, shared_fs = "virtio-fs", and points to the host virtiofsd binary [ref_id=1]. The patches modify src/runtime-rs/Makefile, src/runtime/Makefile, and documentation files to remove virtio_fs_extra_args from default enable_annotations [patch_id=2797570] [patch_id=2799076].

What the fix does

The patches [patch_id=2797570] [patch_id=2799076] remove "virtio_fs_extra_args" from the default enable_annotations lists in both the Go runtime and runtime-rs Makefiles, and update documentation to warn that enabling this annotation can be abused for malicious host-side behavior [ref_id=3]. This prevents pods from passing arbitrary extra arguments to virtiofsd via annotations, closing one avenue for injecting unsafe daemon options. The advisory notes that the underlying issue—virtiofsd accepting absolute symlink paths—is not directly fixed by this change; the patch reduces the attack surface by restricting annotation-based configuration injection.

Preconditions

  • authAttacker must have root-equivalent execution inside the Kata guest VM
  • configHost must use runtime-rs standalone virtio-fs path with virtiofsd running as root with --sandbox none --seccomp none
  • configrootless must be false (default in runtime-rs QEMU configuration)
  • networkAttacker must be able to access the virtio-fs PCI device from inside the guest and build a userspace virtqueue
  • inputAttacker must craft a FUSE_SYMLINK request with an absolute host path as the new symlink name

Reproduction

```shell sudo timeout --foreground --kill-after=10s 600s ctr run --rm \ --runtime /opt/kata/runtime-rs/bin/containerd-shim-kata-v2 \ --runtime-config-path /opt/kata/share/defaults/kata-containers/runtime-rs/configuration-qemu-runtime-rs.toml \ --privileged \ --privileged-without-host-devices \ docker.io/library/kata-go-escape:local \ "$run_id" ``` Inside the guest, the PoC writes a cron payload to /tmp/kata-go-escape-payload, finds the virtio-fs PCI device, takes over a virtio-fs queue from userspace, sends FUSE_INIT, discovers the sandbox under passthrough/, looks up the payload path, and sends raw FUSE_SYMLINK requests with absolute host paths under /etc/cron.d [ref_id=1].

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.