5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / qemu-v8-setup.md MD
# OP-TEE QEMUv8 Environment Setup Log

> Archive note, 2026-04-30: this setup log was captured before the public
> advisory was published on 2026-04-23. The OP-TEE build used for this PoC is
> `4.10.0-rc1-7-g06c4e95e4`. The official advisory for CVE-2026-33317 lists
> patched versions as 4.11 and later. See `README.md` for the current PoC entry
> point.

## Objective

Establish a functional OP-TEE QEMUv8 environment using the official OP-TEE build system
(`repo init -u https://github.com/OP-TEE/manifest.git`) to verify the PKCS#11 TA
and serve as the baseline for C-01 bug reproduction.

---

## Host Environment

| Item | Value |
|------|-------|
| Host OS | Ubuntu 24.04, x86-64 |
| CPU cores | 16 |
| RAM | 62 GB |
| Free disk | ~246 GB |
| GCC | 13.3.0 |
| Python | 3.12.13 (miniconda `audit` env) |
| repo | 2.54 |
| expect | Available on `PATH` |

---

## Step 1 — Create the workspace

```bash
mkdir -p <optee-build>
cd <optee-build>
```

---

## Step 2 — Initialize repo with the qemu_v8 manifest

```bash
repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml --no-clone-bundle
```

The manifest (`qemu_v8.xml` + `common.xml`) pulls these repositories:

| Path | Source | Revision |
|------|--------|----------|
| `build` | OP-TEE/build.git | master |
| `optee_os` | OP-TEE/optee_os.git | master |
| `optee_client` | OP-TEE/optee_client.git | master |
| `optee_test` | OP-TEE/optee_test.git | master |
| `linux` | linaro-swg/linux.git | optee |
| `buildroot` | buildroot/buildroot.git | 2025.05 |
| `qemu` | qemu/qemu.git | v10.0.0 |
| `trusted-firmware-a` | TrustedFirmware-A/trusted-firmware-a.git | v2.14.0 |
| `mbedtls` | Mbed-TLS/mbedtls.git | mbedtls-3.6.5 |
| `u-boot` | u-boot/u-boot.git | v2025.07 |

The build Makefile is set up via a linkfile: `build/qemu_v8.mk` → `build/Makefile`.

---

## Step 3 — Sync all repositories

```bash
repo sync -j8 --no-clone-bundle
```

All 19 repositories synced successfully.

---

## Step 4 — Download cross-compilation toolchains

```bash
cd build
make toolchains -j$(nproc)
```

Installs:
- `toolchains/aarch64/` — AArch64 Linux GCC (for kernel, normal world)
- `toolchains/aarch32/` — ARM32 GCC (for 32-bit TAs)
- `toolchains/rust/` — Rust toolchain

**Issue encountered**: QEMU configure script detected Python from miniconda
(`<python3>`) and failed with:

```
*** Ouch! ***
found no usable distlib, please install it
```

**Fix**:

```bash
pip install distlib
```

---

## Step 5 — Build all components

```bash
make all -j$(nproc) 2>&1 | tee /tmp/optee-build.log
```

Build targets (from `qemu_v8.mk`):

| Target | Output |
|--------|--------|
| `optee-os` | `optee_os/out/arm/core/tee.bin` + PKCS#11 TA |
| `arm-tf` | `trusted-firmware-a/build/qemu/release/bl{1,2,31}.bin` |
| `qemu` | `qemu/build/qemu-system-aarch64` |
| `linux` | `linux/arch/arm64/boot/Image` |
| `buildroot` | `out-br/images/rootfs.cpio.gz` (21 MB) |

Platform configuration (`OPTEE_OS_PLATFORM = vexpress-qemu_armv8a`):
- AArch64 core, GICV3, `CFG_PKCS11_TA=y`
- QEMU: `-smp 2 -cpu max,sme=on -m 1057 -machine virt,acpi=off,secure=on,gic-version=3`

Final staged artifacts in `out/bin/`:

```
bl1.bin  bl2.bin  bl31.bin  bl32.bin  bl32_extra1.bin  bl32_extra2.bin
bl33.bin  Image  linux.bin  rootfs.cpio.gz  rootfs.cpio.uboot  uImage
```

---

## Step 6 — Run QEMUv8 and verify PKCS#11 tests

```bash
make check XTEST_ARGS="-t pkcs11" TIMEOUT=600 DUMP_LOGS_ON_ERROR=y
```

This target uses `build/qemu-check.exp` (an `expect` script) to:
1. Launch QEMU with `-serial mon:stdio -serial file:serial1.log`
2. Wait for the Linux login prompt on ttyAMA0
3. Log in as `root`
4. Run `xtest -t pkcs11`
5. Parse PASS/FAIL output

The exact QEMU command invoked:

```bash
qemu-system-aarch64 \
  -nographic \
  -smp 2 \
  -cpu max,sme=on,pauth-impdef=on \
  -d unimp \
  -semihosting-config enable=on,target=native \
  -m 1057 \
  -bios bl1.bin \
  -initrd rootfs.cpio.gz \
  -kernel Image \
  -append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \
  -machine virt,acpi=off,secure=on,mte=off,gic-version=3,virtualization=false \
  -object rng-random,filename=/dev/urandom,id=rng0 \
  -device virtio-rng-pci,rng=rng0,max-bytes=1024,period=1000 \
  -netdev user,id=vmnic \
  -device virtio-net-device,netdev=vmnic \
  -serial mon:stdio \
  -serial file:serial1.log
```

---

## Result

```
Starting QEMU... done, guest is booted.
Running: xtest -t pkcs11...
##################################################
##################################################
##################################################
##################################################
##################################################
##################################################
#####################
Status: PASS (321 test cases)
```

**321 PKCS#11 test cases PASSED** on the local `optee_os` master snapshot.

The QEMUv8 environment is fully operational and the PKCS#11 TA is exercised
through the full Normal World → TEE call path via `tee-supplicant`.

---

## Workspace layout

```
<optee-build>/
├── build/          ← OP-TEE build Makefile (qemu_v8.mk)
├── buildroot/      ← Buildroot 2025.05
├── linux/          ← Linux kernel (linaro-swg/linux, optee branch)
├── optee_os/       ← OP-TEE OS local master snapshot
├── optee_client/   ← libteec + tee-supplicant
├── optee_test/     ← xtest (incl. PKCS#11 test suite)
├── qemu/           ← QEMU v10.0.0
├── trusted-firmware-a/ ← TF-A v2.14.0
├── toolchains/     ← AArch64 + ARM32 + Rust toolchains
├── out/bin/        ← Staged boot artifacts
└── out-br/         ← Buildroot output (rootfs, host tools)
```

---

## C-01 Reproduction Result (local optee_os master snapshot)

The C-01 PoC (`c01_poc.c`) was cross-compiled for AArch64 and run inside
QEMUv8 via virtio-9p. Key output (2026-04-16):

```
[+] TEEC session with PKCS#11 TA opened
[+] INIT_TOKEN  rc=0x00000000 OK
[+] OPEN_SESSION rc=0x00000000, session_handle=0x00000001
[+] CREATE_OBJECT rc=0x00000000, obj_handle=0x00000001
[+] Object has CKA_LABEL = "AAAAAAAAAAAAAAAA" (16 bytes)
[+] Sending malicious C_GetAttributeValue (attrs_size=8, cli_head.size=16)...
E/TA:  assertion 'BH((char *) b - b->bh.bsize)->prevfree == 0' failed at lib/libutils/isoc/bget.c:1022 in brel()
E/TC:? 0 TA panicked with code 0xffff0000
E/LD:  Status of TA fd02c9da-306c-48c7-a49c-bbd827ae86ee
...
E/LD:  Call stack:
E/LD:   0xc0094a9c
E/LD:   0xc00bd088
E/LD:   0xc00bd550
E/LD:   0xc0082118
E/LD:   0xc0080f3c
E/LD:   0xc009dbe0
E/LD:   0xc00935d8
D/TC:? 0 user_ta_enter:196 tee_user_ta_enter: TA panicked with code 0xffff0000
D/TC:? 0 maybe_release_ta_ctx:696 Releasing panicked TA ctx
[+] GET_ATTRIBUTE_VALUE[0] rc=0xffffffff
```

**Result**: The PKCS#11 TA (`fd02c9da-...`) panicked on the first
`GET_ATTRIBUTE_VALUE` call. The bget allocator assertion at
`lib/libutils/isoc/bget.c:1022` confirms that the heap metadata was
corrupted by the out-of-bounds write at `object.c:872–873`:

```
data_ptr = cli_ref->data;   // = template+16 = end of 16-byte allocation
get_attribute(..., data_ptr, &cli_head.size);  // writes 16 bytes OOB
```

The subsequent `brel()` call detected the corrupted `prevfree` sentinel
in the bget block header that was overwritten, causing `TEE_Panic(0xffff0000)`.

**Bug is confirmed present in the local `4.10.0-rc1-7-g06c4e95e4` build.**

Full logs: `out/bin/c01_nw.log`, `out/bin/c01_sw.log`

---

## Next steps

The bug reproduces on the local `optee_os` master snapshot. The vulnerable
commit (`06c4e95e469c9c89e9ba4a6915d1be7bb8ea6fbc`) introduced the missing
bounds check in `entry_get_attribute_value()`. Reproduction is complete.