Coordinated Disclosure Timeline

Summary

Use-after-free in the Arm Mali GPU kernel driver

Product

Arm Mali

Tested Version

Tested on Pixel 6 Device fingerprint: google/oriole/oriole:12/SQ3A.220705.003/8671607:user/release-keys

Details

Issue 1: Use-after-free in evictable memory of the Arm Mali GPU driver (GHSL-2022-054)

Detailed description.

This is a vulnerability in the Arm Mali gpu driver that affects Pixel 6 and Pixel 6 Pro.

The kbase_mem_evictable_reclaim_scan_objects [1] method is called via the direct reclaim part (through the shrinker kbase_context::reclaim):

int kbase_mem_evictable_init(struct kbase_context *kctx)
{
	INIT_LIST_HEAD(&kctx->evict_list);
	mutex_init(&kctx->jit_evict_lock);

	atomic_set(&kctx->evict_nents, 0);

	kctx->reclaim.count_objects = kbase_mem_evictable_reclaim_count_objects;
	kctx->reclaim.scan_objects = kbase_mem_evictable_reclaim_scan_objects;
	kctx->reclaim.seeks = DEFAULT_SEEKS;
	/* Kernel versions prior to 3.1 :
	 * struct shrinker does not define batch
	 */
	kctx->reclaim.batch = 0;
	register_shrinker(&kctx->reclaim);
	return 0;
}

When there is memory pressure and the fast path for allocating pages from the buddy allocation failed, the kernel may try to call the registered shrinkers to reclaim memory, which will call kbase_mem_evictable_reclaim_scan_objects. This can happen, for example, when a process mmaps a large amount of memory. The method kbase_mem_evictable_reclaim_scan_objects will free up the backing pages of a memory region in the evict_list of the kbase_context:

static
unsigned long kbase_mem_evictable_reclaim_scan_objects(struct shrinker *s,
		struct shrink_control *sc)
{
    ...
	list_for_each_entry_safe(alloc, tmp, &kctx->evict_list, evict_node) {
        ...
		kbase_jit_backing_lost(alloc->reg);

		/* Enough pages have been freed so stop now */
		if (freed > sc->nr_to_scan)
			break;
	}
    ...
}

After that, kbase_jit_backing_lost [2] is called which will free the region by placing it on the jit_destroy_head list:

void kbase_jit_backing_lost(struct kbase_va_region *reg)
{
    ...
	list_move(&reg->jit_node, &kctx->jit_destroy_head);   //<-------- this will schedule the region to be freed

	schedule_work(&kctx->jit_work);
}

However, a kbase_va_region can be allocated using kbase_jit_allocate and have a reference held in kbase_context::jit_alloc:

static int kbase_jit_allocate_process(struct kbase_jd_atom *katom)
{
    ...
	for (i = 0, info = katom->softjob_data; i < count; i++, info++) {
        ...
		reg = kbase_jit_allocate(kctx, info, ignore_pressure_limit);
	/* Bind it to the user provided ID. */
		kctx->jit_alloc[info->id] = reg;
	}
    ...

As this reference is not removed when the kbase_va_region is free’d, a use-after-free can be triggered as follows:

  1. Create a kbase_va_region using kbase_jit_allocate, and then move it to the evict_list by adding the KBASE_REG_DONT_NEED flag to the region using the KBASE_IOCTL_MEM_FLAGS_CHANGE ioctl.
  2. Trigger a direct reclaim to free the region and kbase_context::jit_alloc will hold a pointer to a free’d kbase_va_region object.
  3. Use kbase_jit_free to access the free’d pointer in jit_alloc and a use-after-free will be triggered.

Impact

This issue is a use-after-free in the Arm Mali Kernel driver.

Resources

  1. https://android.googlesource.com/kernel/google-modules/gpu/+/refs/heads/android-gs-raviole-5.10-android12-qpr3/mali_kbase/mali_kbase_mem_linux.c#670
  2. https://android.googlesource.com/kernel/google-modules/gpu/+/refs/heads/android-gs-raviole-5.10-android12-qpr3/mali_kbase/mali_kbase_mem.c#4281

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-2022-054 in any communication regarding this issue.

Notes

  1. The exact reply from the Android security team: Hello, The Android security team has conducted an additional review of this report and believes that this is a device-specific issue instead of a security vulnerability on the Android Platform. Since the area impacted is owned by ARM, we have shared this report with them for investigation and remediation. We also encourage you to contact your device’s customer support to further assist with this issue. If you have additional information you believe we should use to reassess this report, please let us know. Thank you, Android Security Team 

  2. The exact reply from the Android security team: Hello, Thank you for your support of the Android ecosystem! This issue is outside of this program’s scope, however, we are doing our best to help our partner fix the issue. We will continue to work with our partner and let you know as we have any further questions. Best, Android Security Team