Coordinated Disclosure Timeline
- 2022-01-15: Reported to Android security team as ticket 214577962.
- 2022-01-17: Assigned Android ID as 215001024.
- 2022-01-19: Assigned High severity
- 2022-03-31: Android security team informed me that the issue is fixed.
- 2022-05-27: CVE-2022-20186 was assigned
- 2022-06-06: Disclosed as CVE-2022-20186 in the Pixel Update Bulletin in June 2022.
- 2022-07-28: We were informed by Vitaly Nikolenko and Jann Horne that Arm may have assigned this bug as CVE-2022-28348 separately and published a fix on 2022-04-02.
Summary
Improper validation of input data can lead to free’d memory being accessible from the GPU, which can lead to arbitrary memory access.
Product
Arm Mali
Tested Version
Android before June Security patch
Details
Issue 1: Use-after-free in alias memory of the Arm Mali gpu kernel driver (GHSL-2022-053
)
This is a vulnerability in the Arm Mali GPU driver that affects Pixel 6 and Pixel 6 Pro.
In the kbase_mem_alias
method, the number of pages for the alias region is computed by multiplying nents
and stride
, both are parameters supplied by the user using the KBASE_IOCTL_MEM_ALIAS
ioctl call. The multiplication can overflow, resulting in an alias region with too few pages [1].
u64 kbase_mem_alias(struct kbase_context *kctx, u64 *flags, u64 stride,
u64 nents, struct base_mem_aliasing_info *ai,
u64 *num_pages)
{
...
if ((nents * stride) > (U64_MAX / PAGE_SIZE)) //<---------- check can be bypassed when product overflow uint64_t
/* 64-bit address range is the max */
goto bad_size;
/* calculate the number of pages this alias will cover */
*num_pages = nents * stride;
For example, consider the following order of memory mapping in the GPU.
- Allocate 2 regions of 3 pages each in the GPU using the
KBASE_IOCTL_MEM_ALLOC
ioctl and then usemmap
to map them to the GPU. Denote these as regions A and B. These regions will be used as memory alias for the alias region that will be created later. - Allocate another region of 3 pages and
mmap
it to the GPU. This region will be overflowed by the alias region later. Denote this as region C. - Create a memory alias region using the
KBASE_IOCTL_MEM_ALIAS
ioctl withstride
set to 2 ** 63 + 1 andnents
sets to 2. Alias this region with regions A and B. - Because the GPU allocates regions by searching for free regions from top down, if the address of A is addrA, then the memory addresses of these regions will be the following:
- A: addrA
- B: addrA - 0x3000
- C: addrB - 0x3000
- Alias: addrC - 0x2000
When the alias region is created, entries will be inserted into the GPU pagetable
and the range of addresses between [AliasAddr, AliasAddr + 0x3000)
will be now backed by the pages in region A, while [AliasAddr + stride, AliasAddr + stride + 0x3000)
will be backed by the pages in region B. However, because [AliasAddr + 0x2000, AliasAddr + 0x3000)
overlaps with region C, the pagetable
entry inserted when region C is created will be overwritten and part of region C will now be backed by pages in region A. However, since this page is owned by region A, it’ll be free’d after both region A and the alias region are unmapped, while the pagetable
entry for region C still points to the physical address of the page that is now free’d. This means if another process now allocates and maps memory to the Mali gpu, it may ended up reusing this free’d page that is still referenced in the pagetable
of region C. In other words, by accessing region C with the GPU, the process can now access pages in another process that happens to have reclaimed this page.
Impact
This vulnerability can be exploited to achieve arbitrary kernel code execution from the app domain.
CVE
- CVE-2022-20186
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-053
in any communication regarding this issue.