Coordinated Disclosure Timeline

Summary

GPU memory in the Arm Mali GPU can be accessed after it is freed

Project

Arm Mali

Tested Version

Tested on Pixel 8 with November 2024 patch and Mali Driver r53 on a VM

Details

Freed use io memory can be accessed (GHSL-2024-356)

Detailed description.

In the Mali GPU driver that uses CSF, a kbase_queue can be created and then bound to a kbase_queue_group. It can then map memory to the user space via mmap. During which, memory pages managed by the GPU device are allocated to the kbase_queue:

static int kbase_csf_cpu_mmap_user_io_pages(struct kbase_context *kctx, struct vm_area_struct *vma)
{
  unsigned long cookie = vma->vm_pgoff - PFN_DOWN(BASEP_MEM_CSF_USER_IO_PAGES_HANDLE);
  size_t nr_pages = vma_pages(vma);
  struct kbase_queue *queue;
  int err = 0;
  ...
  err = kbase_csf_alloc_command_stream_user_pages(kctx, queue);  //<---- 1.
  ...
}

At 1. in the above, memory pages are allocated from and assigned to the queue->phys array. These pages are freed when the mapped vma is closed and kbase_csf_user_io_pages_vm_close is called:

static void kbase_csf_user_io_pages_vm_close(struct vm_area_struct *vma)
{
  ...
  mutex_lock(&kctx->csf.lock);
  kbase_csf_queue_unbind(queue, is_process_exiting(vma));   //<----- 2.
  mutex_unlock(&kctx->csf.lock);
  ...
}

In 2., kbase_csf_queue_unbind will remove the connection between the kbase_queue and the kbase_queue_group that it binds to and then frees the pages. This ensures that the pages cannot be accessed from user space via the vma.

However, a kbase_queue can also be disconnected with the kbase_queue_group that it binds to when the kbase_queue_group is terminated, for example, by calling the KBASE_IOCTL_CS_QUEUE_GROUP_TERMINATE ioctl. This will reset the kbase_queue to the KBASE_CSF_QUEUE_UNBOUND state and allow it to bind with another kbase_queue_group. If mmap is used on this kbase_queue after this new binding happens, new memory pages will be allocated, overwriting the existing pages that are stored in queue->phys.

In particular, if the vma mapped prior to the rebinding is then closed, kbase_csf_user_io_pages_vm_close will free the pages in queue->phys, which are the new pages that are allocated after the rebinding, and these pages are still mapped to the new userspace vma. This causes a use-after-free in memory pages allocated by the Mali driver.

Impact

This issue can be exploited to gain arbitrary kernel code execution from a malicious user space application.

CVE

Credit

This issue was discovered and reported by GHSL team member @m-y-mo (Man Yue Mo).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2024-356 in any communication regarding this issue.