README.md
Rendering markdown...
# 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.