
QEMU-based lab for reproducing CVE-2022-46395 race condition in Arm Mali r36p0 GPU driver. Includes PoC, build scripts, and initramfs packaging for local vulnerability research and regression testing.
This repository contains a QEMU/no-Mali lab for reproducing the portable trigger condition of CVE-2022-46395 against the Arm Mali r36p0 driver lineage.
The lab is intended for local vulnerability research and regression testing. It
does not carry the Pixel-specific privilege escalation payload from the original
exploit. In LAB_QEMU mode the PoC stops after demonstrating that the
soft-event/user-buffer race window was reached.
poc/: QEMU-adapted CVE-2022-46395 PoC. Android logging and property calls
are replaced, and Pixel kernel text patching is disabled under LAB_QEMU.src/google-gpu-raviole-android13/: Google Pixel GPU module source from
android.googlesource.com/kernel/google-modules/gpu, branch
android-gs-raviole-5.10-android13. The included mali_kbase/Kbuild
identifies the driver as r36p0-01eac0.scripts/: build, initramfs packaging, QEMU boot, and one-shot reproduction
helpers.docs/: local analysis notes and reproduction reports.logs/: selected evidence logs from successful local runs.Generated binaries, initramfs archives, object files, and most runtime logs are ignored by Git. Rebuild them locally with the scripts below.
The scripts were used on a Linux VM with:
bash, make, gcc, file, cpio, gzip, modinfobusybox at /bin/busyboxqemu-system-x86_64By default the scripts expect the kernel tree and boot image at:
../build/linux-5.10-kasan
../build/linux-5.10-kasan/arch/x86/boot/bzImage
You can override those paths with KDIR and KERNEL_IMAGE.
Clone the repository and enter it:
git clone https://github.com/Gao-Zuin/cve-2022-46395-qemu.git
cd cve-2022-46395-qemu
Run the full build/package/boot flow:
MAX_ATTEMPTS=2000 ./scripts/reproduce.sh
If your KASAN kernel is not in the default sibling ../build directory:
KDIR=/path/to/linux-5.10-kasan \
KERNEL_IMAGE=/path/to/linux-5.10-kasan/arch/x86/boot/bzImage \
MAX_ATTEMPTS=2000 \
./scripts/reproduce.sh
The successful local run used this timing:
MAX_ATTEMPTS=2000 UNMAP_OFFSET_NS=-800000 ./scripts/reproduce.sh
For more verbose attempt logging:
MAX_ATTEMPTS=2000 VERBOSE_ATTEMPTS=1 UNMAP_OFFSET_NS=-800000 \
./scripts/reproduce.sh
The one-shot script is equivalent to:
./scripts/build_r36p0_no_mali.sh
./scripts/build_poc.sh
MAX_ATTEMPTS=2000 UNMAP_OFFSET_NS=-800000 ./scripts/package_initramfs.sh
./scripts/run_qemu.sh
Useful environment variables:
KDIR: kernel build tree used for compiling mali_kbase.koKERNEL_IMAGE: bzImage passed to QEMUQEMU_LOG: output log pathQEMU_MEM: QEMU memory size, default 1536MQEMU_SMP: QEMU CPU count, default 3MAX_ATTEMPTS: PoC retry limit, default 2000UNMAP_OFFSET_NS: race timing offset, default -800000VERBOSE_ATTEMPTS=1: print per-attempt detailsKASAN_UAF_MODE=1: load the module with the KASAN UAF probe option used by
scripts/reproduce_kasan_uaf.shA successful run prints lines like:
mali mali.0: Kernel DDK version r36p0-01eac0
r36p0-01eac0 (UK version 11.34)
/dev/mali0
finished reset: 703956220 fault: 682115150 68 err 0 read 3
qemu lab mode: CVE-2022-46395 soft-event/user-buffer race reproduced
qemu lab mode: reproduction completed after 17 attempts
[init] PoC status: 0
The reference evidence log is:
logs/qemu-cve-2022-46395-r36p0-unmap-minus800us.log
The key success condition is err=0, read=3, and fault < reset. That
indicates the race window was reached against r36p0-01eac0 in no-Mali QEMU.
MAX_ATTEMPTS or tune UNMAP_OFFSET_NS.