QEMUtiny - QEMU escape vulnerability (cxl only)

Tiberium1 pts0 comments

pocs/qemu at main · v12-security/pocs · GitHub

//files/disambiguate" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

//files/disambiguate;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

v12-security

pocs

Public

Notifications<br>You must be signed in to change notification settings

Fork<br>71

Star<br>367

FilesExpand file tree

main

/qemu<br>Copy path

Directory actions

More options<br>More options

Directory actions

More options<br>More options

Latest commit

History<br>History<br>History

main

/qemu

Top

Folders and files<br>NameNameLast commit message<br>Last commit date<br>parent directory<br>..<br>images

images

README.md

README.md

bios-256k.bin

bios-256k.bin

efi-e1000.rom

efi-e1000.rom

efi-e1000e.rom

efi-e1000e.rom

kvmvapic.bin

kvmvapic.bin

linuxboot_dma.bin

linuxboot_dma.bin

poc.c

poc.c

qemu-system-x86_64

qemu-system-x86_64

run_qemu_shell.sh

run_qemu_shell.sh

setup_guest.sh

setup_guest.sh

vgabios-stdvga.bin

vgabios-stdvga.bin

View all files

README.md<br>Outline<br>QEMUtiny

qemu.mp4

Abstract

QEMUtiny is a memory corruption vulnerability in QEMU's implementation of CXL Type-3<br>device emulation, reported against QEMU master 007b29752e and confirmed<br>working against 5e61afe (May 11, 2026).

QEMUtiny was discovered autonomously with V12 by Aaron Esau of the<br>V12 security team.

Want to find issues like this in your own code? Try V12 at v12.sh.

The PoC chains two CXL mailbox bugs in hw/cxl/cxl-mailbox-utils.c: an<br>out-of-bounds read in GET_LOG, followed by an out-of-bounds write in<br>SET_FEATURE.

OOB read: cmd_logs_get_log() treats the CEL log offset as an array<br>index in the memmove() source expression even though the CXL mailbox<br>offset is in bytes.

OOB write: cmd_features_set_feature() accepts byte offsets into<br>several small feature write-attribute structures without checking that<br>offset + bytes_to_copy stays inside the selected structure.

We reported the bugs upstream. Maintainers state CXL support is currently for at non-virtualization use cases, so we feel comfortable release the PoC publicly.

The included poc.c is a working exploit that drives the emulated CXL mailbox from the guest through the device BAR. It depends on offsets for the specific QEMU build and host libc layout.<br>The exploit can be weaponized to work reliably across many QEMU versions using the OOB read to scan memory. However this is out of scope for this PoC.

"QEMUtiny"?

QEMU + Mutiny.

Building

gcc -O2 -Wall -Wextra -o exp poc.c

The reproducer must be run as root inside the guest because it writes PCI config<br>space and mmaps the CXL device BAR through sysfs.

sudo ./exp

One-line version:

git clone https://github.com/v12-security/pocs.git && cd pocs/qemu && gcc -O2 -Wall -Wextra -o exp poc.c && sudo ./exp

Test Setup

Use ./run_qemu_shell.sh. Then in the guest, use /exp

poc.c assumes the CXL Type-3 device appears in the guest at:

/sys/bus/pci/devices/0000:35:00.0

and that BAR2 is exposed as:

/sys/bus/pci/devices/0000:35:00.0/resource2

If your guest enumerates the device at a different BDF, update the two sysfs<br>paths in main().

How It Works

Mailbox access. The guest enables PCI memory decoding for the CXL device,<br>maps BAR2, and sends CXL mailbox commands by writing the mailbox payload,<br>command, and control registers directly.

CEL out-of-bounds read. cmd_logs_get_log() checks the requested CEL<br>range as if offset were a byte offset, but then performs pointer arithmetic<br>on cci->cel_log as a struct cel_log *. poc.c uses<br>GET_LOG_OOB_BASE_OFFSET to land just past the CEL buffer and read adjacent<br>QEMU CXL state.

QEMU address discovery. The out-of-bounds CEL read leaks a CXL mailbox<br>command handler pointer and the CXLType3Dev heap address. The handler<br>pointer gives the QEMU PIE base for this build.

Rank sparing overflow. The demo sends SET_FEATURE / RANK_SPARING with<br>a non-zero feature offset and a large payload. The rank sparing case copies<br>into ct3d->rank_sparing_wr_attrs + hdr->offset without bounding the copy to<br>sizeof(ct3d->rank_sparing_wr_attrs), so the payload continues into later<br>CXLType3Dev fields.

Fake memory dispatch state. The overflowed payload plants enough fake<br>FlatView, dispatch, section, MemoryRegion, and MemoryRegionOps state<br>for the sanitize path to call a...

qemu mailbox read offset device guest

Related Articles