# How to Use the QEMU CXL PoC Bootloader: Complete Setup and Execution Guide

> Learn how to use the QEMU CXL PoC bootloader to demonstrate CXL mailbox escape vulnerabilities. This guide covers setup and execution for the two-stage bootloader.

- Repository: [bikini/exploitarium](https://github.com/bikini/exploitarium)
- Tags: how-to-guide
- Published: 2026-09-07

---

**The QEMU CXL PoC bootloader is a two-stage system comprising a 16-bit BIOS bootloader (`boot.asm`) that loads a 32-bit protected-mode payload ([`stage2.c`](https://github.com/bikini/exploitarium/blob/main/stage2.c)) from a floppy image to demonstrate CXL mailbox escape vulnerabilities in QEMU.**

The `bikini/exploitarium` repository hosts a proof-of-concept that demonstrates host-side code execution through CXL (Compute Express Link) Type 3 device emulation vulnerabilities in QEMU. The **QEMU CXL PoC bootloader** serves as the entry point for this exploit, providing a minimal real-mode bootstrap that transitions into a sophisticated protected-mode payload capable of manipulating CXL PCI topology and mailbox registers.

## Bootloader Architecture and Components

The bootloader implementation resides in the `qemu-cxl-type3-mailbox-escape-poc/` directory and consists of two distinct execution stages that bridge BIOS initialization with the exploit payload.

### Real-Mode Bootstrap (boot.asm)

The first stage is implemented in `boot.asm` as a 16-bit BIOS bootloader that occupies the Master Boot Record (MBR) of the floppy image. This assembly code performs minimal hardware initialization, clears segment registers, establishes a stack at `0x7c00`, and saves the boot drive identifier passed by the BIOS in the `DL` register. Using BIOS interrupt `0x13` (ah=0x02), it reads **16 sectors** starting from **sector 2** of the floppy into physical memory at address `0x8000`, which contains the pre-built stage2 binary.

### Protected-Mode Payload (stage2.c)

The second stage resides in [`stage2.c`](https://github.com/bikini/exploitarium/blob/main/stage2.c) as a freestanding 32-bit C binary compiled without standard library dependencies. This payload executes immediately after the bootloader switches the CPU to protected mode, configuring the CXL PCI topology, driving the CXL mailbox registers to leak host pointers, and ultimately triggering a host-side `system()` call through a forged memory-region callback. Unlike the bootloader, which contains no exploit logic, [`stage2.c`](https://github.com/bikini/exploitarium/blob/main/stage2.c) houses all vulnerability-specific code that proves code execution inside the QEMU process.

## Building the QEMU CXL PoC Bootloader

Creating the bootable floppy image requires assembling the bootloader, compiling the stage2 payload, and linking them into a flat binary format suitable for QEMU emulation.

### Prerequisites and Build Scripts

The build process depends on **NASM** (Netwide Assembler) for the bootloader and a **GCC cross-compiler** capable of generating 32-bit x86 code (multilib support required). The [`build.sh`](https://github.com/bikini/exploitarium/blob/main/build.sh) script automates the entire compilation pipeline:

```bash

# Assemble the 16-bit bootloader

nasm -f bin boot.asm -o boot.bin

# Compile stage2 as freestanding 32-bit code

gcc -ffreestanding -m32 -nostdlib -c stage2.c -o stage2.o

# Link using the custom linker script to produce flat binary

ld -m elf_i386 -T stage2.ld stage2.o -o stage2.bin

```

The linker script `stage2.ld` ensures the stage2 binary is position-independent and loads at the expected physical address `0x8000`, matching the bootloader's jump target.

### Generating the Floppy Image

The build script combines the bootloader and stage2 binary into a 1.44MB floppy image (`poc.img`) by writing `boot.bin` to sector 1 and `stage2.bin` to sector 2:

```bash
dd if=/dev/zero of=poc.img bs=512 count=2880
dd if=boot.bin of=poc.img bs=512 count=1 conv=notrunc
dd if=stage2.bin of=poc.img bs=512 seek=1 conv=notrunc

```

## Executing the Exploit in QEMU

Running the **QEMU CXL PoC bootloader** requires specific command-line arguments to enable CXL Type 3 device emulation and attach the exploit floppy image.

### QEMU Configuration Parameters

The [`run.sh`](https://github.com/bikini/exploitarium/blob/main/run.sh) script launches QEMU with the exact configuration required for the exploit:

```bash
qemu-system-x86_64 \
  -machine type=q35,cxl=on \
  -device cxl-type3,bus=root_bus0,memdev=cxl-mem0,id=cxl-dcd0 \
  -object memory-backend-file,id=cxl-mem0,share=on,mem-path=cxl-region-0.raw,size=256M \
  -device cxl-type3,bus=root_bus0,memdev=cxl-volatile0,id=cxl-dcd1 \
  -object memory-backend-file,id=cxl-volatile0,share=on,mem-path=cxl-region-1.raw,size=256M \
  -fda poc.img \
  -serial stdio

```

This configuration enables CXL support on the q35 machine type, instantiates two CXL Type 3 devices with 256 MiB volatile and 256 MiB dynamic-capacity memory backends, and attaches `poc.img` as floppy drive A (fda).

### Boot Sequence and Exploit Flow

When QEMU boots with the floppy attached, the **QEMU CXL PoC bootloader** executes the following sequence:

1. **Real-mode initialization**: Clears interrupts, sets up segment registers (`DS`, `ES`, `SS`), and establishes the stack pointer.
2. **Disk I/O**: Invokes `int 0x13` to load 16 sectors (8 KB) from sector 2 into the buffer at physical address `0x8000`.
3. **Protected mode transition**: Loads a Global Descriptor Table (GDT) with code and data segments, sets the Protection Enable (PE) bit in Control Register 0 (`CR0`), and performs a far jump to `0x08:0x8000` to enter 32-bit protected mode.
4. **Payload execution**: The stage2 entry point configures the CXL device mailbox, sends commands to the CXL root complex, and manipulates memory region callbacks to escape the VM and create the marker file `/tmp/qemu_cxl_escape_marker` on the host filesystem.

## Technical Deep Dive: Assembly Boot Sequence

The `boot.asm` source contains the precise machine instructions that bridge BIOS hand-off to the C payload. The code loads the GDT descriptor and switches CPU modes using privileged instructions:

```asm
; Switch to protected mode
lgdt [gdt_desc]           ; Load Global Descriptor Table
mov eax, cr0
or eax, 1                 ; Set Protection Enable bit
mov cr0, eax
jmp 0x08:pmode            ; Far jump to protected mode

BITS 32
pmode:
    mov ax, 0x10          ; Data segment selector
    mov ds, ax
    mov esp, 0x90000      ; New stack for protected mode
    jmp 0x08:0x8000       ; Jump to stage2 entry point

```

The GDT defines two segments: a code segment at selector `0x08` (base 0, limit 4GB) and a data segment at selector `0x10`. The `jmp 0x08:0x8000` instruction flushes the CPU pipeline and begins executing the 32-bit payload located at the memory address where the bootloader loaded [`stage2.c`](https://github.com/bikini/exploitarium/blob/main/stage2.c).

## Summary

The **QEMU CXL PoC bootloader** demonstrates a complete chain of trust exploitation from BIOS boot to host code execution:

- The repository at `bikini/exploitarium` provides a two-stage bootloader (`boot.asm` and [`stage2.c`](https://github.com/bikini/exploitarium/blob/main/stage2.c)) specifically designed to exploit CXL Type 3 mailbox implementations in QEMU.
- Building requires NASM and GCC with 32-bit support, using [`build.sh`](https://github.com/bikini/exploitarium/blob/main/build.sh) to produce the `poc.img` floppy image.
- Execution depends on QEMU with CXL support enabled, configured with 256 MiB volatile and dynamic-capacity memory regions.
- The bootloader transitions from real mode to protected mode via GDT initialization and a far jump to `0x8000`, handing control to the [`stage2.c`](https://github.com/bikini/exploitarium/blob/main/stage2.c) payload.
- Successful exploitation creates `/tmp/qemu_cxl_escape_marker` on the host, proving arbitrary code execution within the QEMU process.

## Frequently Asked Questions

### What hardware and software are required to run the QEMU CXL PoC bootloader?

You need a Linux system with QEMU version 6.2 or later compiled with CXL support, NASM (Netwide Assembler), and GCC with multilib support for 32-bit compilation (`gcc -m32`). The PoC runs entirely in emulation, so no physical CXL hardware is required.

### Is the QEMU CXL PoC bootloader safe to run on production systems?

**No.** This proof-of-concept is designed specifically to demonstrate security vulnerabilities and achieves host-side code execution. Only run this bootloader in isolated virtual environments or dedicated research sandboxes, as it intentionally exploits memory safety issues to create arbitrary files on the host filesystem.

### What CXL device configuration does the exploit emulate?

The bootloader operates alongside QEMU's emulation of CXL Type 3 devices with both volatile and dynamic-capacity memory regions. The [`run.sh`](https://github.com/bikini/exploitarium/blob/main/run.sh) script configures two 256 MiB memory backends (`cxl-region-0.raw` and `cxl-region-1.raw`) attached to the CXL root complex, which the stage2 payload manipulates through PCI configuration space and mailbox registers.

### How does the bootloader transition from real mode to protected mode?

The transition occurs in four steps: first, the code disables interrupts and loads a minimal GDT descriptor using the `lgdt` instruction; second, it modifies Control Register 0 (`CR0`) to set the Protection Enable bit; third, it executes a far jump to selector `0x08` to flush the CPU pipeline; finally, it initializes 32-bit segment registers and jumps to the stage2 entry point at physical address `0x8000`.