# 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 cd ``` --- ## 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 (``) 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 ``` / ├── 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.