Android Library Only Instrumentation sort of fixed.
[kernel/swap-modules.git] / kprobe / dbi_kprobes_deps.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  modules/kprobe/dbi_kprobes_deps.h
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2006-2010
20  *
21  * 2008-2009    Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
22  *              Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
23  * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts 
24  *
25
26  */
27
28 #include <linux/module.h>
29 #include <linux/sched.h>
30
31 #include <asm/pgtable.h>
32
33 #include "dbi_kprobes_deps.h"
34 #include "dbi_kdebug.h"
35
36
37 #include <linux/slab.h>
38
39 unsigned int *sched_addr;
40 unsigned int *fork_addr;
41
42
43 #define GUP_FLAGS_WRITE                  0x1
44 #define GUP_FLAGS_FORCE                  0x2
45 #define GUP_FLAGS_IGNORE_VMA_PERMISSIONS 0x4
46 #define GUP_FLAGS_IGNORE_SIGKILL         0x8
47
48 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
49 struct mm_struct* init_mm_ptr;
50 struct mm_struct init_mm;
51 #endif
52
53
54 DECLARE_MOD_CB_DEP(kallsyms_search, unsigned long, const char *name);
55 DECLARE_MOD_FUNC_DEP(access_process_vm, int, struct task_struct * tsk, unsigned long addr, void *buf, int len, int write);
56 DECLARE_MOD_FUNC_DEP(copy_to_user_page, void, struct vm_area_struct *vma, struct page *page, unsigned long uaddr, void *dst, const void *src, unsigned long len);
57
58 DECLARE_MOD_FUNC_DEP(find_extend_vma, struct vm_area_struct *, struct mm_struct * mm, unsigned long addr);
59
60 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
61 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)
62 DECLARE_MOD_FUNC_DEP(handle_mm_fault, int, struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access);
63 #endif
64 #else
65 DECLARE_MOD_FUNC_DEP(handle_mm_fault, int, struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, unsigned int flags);
66 #endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30) */
67
68 DECLARE_MOD_FUNC_DEP(get_gate_vma, struct vm_area_struct *, struct task_struct *tsk);
69
70 #ifdef CONFIG_HUGETLB_PAGE
71 DECLARE_MOD_FUNC_DEP(follow_hugetlb_page, int, struct mm_struct *mm, struct vm_area_struct *vma, struct page **pages, struct vm_area_struct **vmas, unsigned long *position, int *length, int i, int write);
72 #endif
73
74 #ifdef  __HAVE_ARCH_GATE_AREA
75 DECLARE_MOD_FUNC_DEP(in_gate_area, int, struct task_struct *tsk,unsigned long addr);
76 #else
77 DECLARE_MOD_FUNC_DEP(in_gate_area_no_task, int, unsigned long addr);
78 #endif
79 DECLARE_MOD_FUNC_DEP(follow_page, \
80                 struct page *, struct vm_area_struct * vma, \
81                 unsigned long address, unsigned int foll_flags);
82 DECLARE_MOD_FUNC_DEP(__flush_anon_page, \
83                 void, struct vm_area_struct *vma, struct page *page, \
84                 unsigned long vmaddr);
85 DECLARE_MOD_FUNC_DEP(vm_normal_page, \
86                 struct page *, struct vm_area_struct *vma, \
87                 unsigned long addr, pte_t pte);
88
89 DECLARE_MOD_FUNC_DEP(flush_ptrace_access, \
90                 void, struct vm_area_struct *vma, struct page *page, \
91                 unsigned long uaddr, void *kaddr, unsigned long len, int write);
92
93
94 #if (LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 16))
95 DECLARE_MOD_FUNC_DEP(put_task_struct, \
96                 void, struct task_struct *tsk);
97 #else 
98 DECLARE_MOD_FUNC_DEP(put_task_struct, \
99                 void, struct rcu_head * rhp);
100 #endif
101
102         DECLARE_MOD_DEP_WRAPPER(access_process_vm, int, struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
103 IMP_MOD_DEP_WRAPPER (access_process_vm, tsk, addr, buf, len, write)
104
105         DECLARE_MOD_DEP_WRAPPER (find_extend_vma, struct vm_area_struct *, struct mm_struct * mm, unsigned long addr)
106 IMP_MOD_DEP_WRAPPER (find_extend_vma, mm, addr)
107
108 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
109 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)
110         DECLARE_MOD_DEP_WRAPPER (handle_mm_fault, \
111                         int, struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
112 IMP_MOD_DEP_WRAPPER (handle_mm_fault, mm, vma, address, write_access)
113 #endif
114 #else
115         DECLARE_MOD_DEP_WRAPPER (handle_mm_fault, \
116                         int, struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, unsigned int flags)
117 IMP_MOD_DEP_WRAPPER (handle_mm_fault, mm, vma, address, flags)
118 #endif
119
120         DECLARE_MOD_DEP_WRAPPER (get_gate_vma, \
121                         struct vm_area_struct *, struct task_struct *tsk)
122 IMP_MOD_DEP_WRAPPER (get_gate_vma, tsk)
123
124 #ifdef CONFIG_HUGETLB_PAGE
125         DECLARE_MOD_DEP_WRAPPER (follow_hugetlb_page, int, struct mm_struct *mm, struct vm_area_struct *vma, struct page **pages, struct vm_area_struct **vmas, unsigned long *position, int *length, int i, int write)
126         IMP_MOD_DEP_WRAPPER (follow_hugetlb_page, mm, vma, pages, vmas, position, length, i, write)
127 #endif
128
129 #ifdef  __HAVE_ARCH_GATE_AREA
130         DECLARE_MOD_DEP_WRAPPER (in_gate_area, int, struct task_struct *tsk, unsigned long addr)
131         IMP_MOD_DEP_WRAPPER (in_gate_area, tsk, addr)
132 #else
133         DECLARE_MOD_DEP_WRAPPER (in_gate_area_no_task, int, unsigned long addr)
134 IMP_MOD_DEP_WRAPPER (in_gate_area_no_task, addr)
135 #endif
136
137 #if (LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 11))
138         DECLARE_MOD_DEP_WRAPPER (follow_page, \
139                         struct page *, struct vm_area_struct * vma, \
140                         unsigned long address, unsigned int foll_flags)
141 IMP_MOD_DEP_WRAPPER (follow_page, vma, address, foll_flags)
142 #endif
143         DECLARE_MOD_DEP_WRAPPER (__flush_anon_page, \
144                         void, struct vm_area_struct *vma, \
145                         struct page *page, unsigned long vmaddr)
146 IMP_MOD_DEP_WRAPPER (__flush_anon_page, vma, page, vmaddr)
147
148         DECLARE_MOD_DEP_WRAPPER(vm_normal_page, \
149                         struct page *, struct vm_area_struct *vma, \
150                         unsigned long addr, pte_t pte)
151 IMP_MOD_DEP_WRAPPER (vm_normal_page, vma, addr, pte)
152
153         DECLARE_MOD_DEP_WRAPPER (flush_ptrace_access, \
154                         void, struct vm_area_struct *vma, struct page *page, \
155                         unsigned long uaddr, void *kaddr, unsigned long len, int write)
156 IMP_MOD_DEP_WRAPPER (flush_ptrace_access, vma, page, uaddr, kaddr, len, write)
157
158         DECLARE_MOD_DEP_WRAPPER(copy_to_user_page, void, struct vm_area_struct *vma, struct page *page, unsigned long uaddr, void *dst, const void *src, unsigned long len)
159 IMP_MOD_DEP_WRAPPER (copy_to_user_page, vma, page, uaddr, dst, src, len)
160
161
162 int init_module_dependencies()
163 {
164
165 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
166         init_mm_ptr = (struct mm_struct*) kallsyms_search ("init_mm");
167         memcmp(init_mm_ptr, &init_mm, sizeof(struct mm_struct));
168 #endif
169
170 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)
171         INIT_MOD_DEP_VAR(handle_mm_fault, handle_mm_fault);
172 #endif
173
174         INIT_MOD_DEP_VAR(flush_ptrace_access, flush_ptrace_access);
175         INIT_MOD_DEP_VAR(find_extend_vma, find_extend_vma);
176         INIT_MOD_DEP_VAR(get_gate_vma, get_gate_vma);
177
178 #ifdef CONFIG_HUGETLB_PAGE
179         INIT_MOD_DEP_VAR(follow_hugetlb_page, follow_hugetlb_page);
180 #endif
181
182 #ifdef  __HAVE_ARCH_GATE_AREA
183         INIT_MOD_DEP_VAR(in_gate_area, in_gate_area);
184 #else
185         INIT_MOD_DEP_VAR(in_gate_area_no_task, in_gate_area_no_task);
186 #endif
187         INIT_MOD_DEP_VAR(follow_page, follow_page);
188
189         INIT_MOD_DEP_VAR(__flush_anon_page, __flush_anon_page);
190         INIT_MOD_DEP_VAR(vm_normal_page, vm_normal_page);
191         INIT_MOD_DEP_VAR(access_process_vm, access_process_vm);
192
193 #if (LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 16))
194 # if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11))
195         INIT_MOD_DEP_VAR(put_task_struct, put_task_struct);
196 # else
197         INIT_MOD_DEP_VAR(put_task_struct, __put_task_struct);
198 # endif
199 #else /*2.6.16 */
200         INIT_MOD_DEP_VAR(put_task_struct, __put_task_struct_cb);
201 #endif
202
203         INIT_MOD_DEP_VAR(copy_to_user_page, copy_to_user_page);
204
205         return 0;
206 }
207
208 #define GUP_FLAGS_WRITE                  0x1
209 #define GUP_FLAGS_FORCE                  0x2
210 #define GUP_FLAGS_IGNORE_VMA_PERMISSIONS 0x4
211 #define GUP_FLAGS_IGNORE_SIGKILL         0x8
212
213 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
214 static inline int use_zero_page(struct vm_area_struct *vma)
215 {
216         /*
217          * We don't want to optimize FOLL_ANON for make_pages_present()
218          * when it tries to page in a VM_LOCKED region. As to VM_SHARED,
219          * we want to get the page from the page tables to make sure
220          * that we serialize and update with any other user of that
221          * mapping.
222          */
223         if (vma->vm_flags & (VM_LOCKED | VM_SHARED))
224                 return 0;
225         /*
226          * And if we have a fault routine, it's not an anonymous region.
227          */
228         return !vma->vm_ops || !vma->vm_ops->fault;
229 }
230
231 int __get_user_pages_uprobe(struct task_struct *tsk, struct mm_struct *mm,
232                      unsigned long start, int len, int flags,
233                 struct page **pages, struct vm_area_struct **vmas)
234 {
235         int i;
236         unsigned int vm_flags = 0;
237         int write = !!(flags & GUP_FLAGS_WRITE);
238         int force = !!(flags & GUP_FLAGS_FORCE);
239         int ignore = !!(flags & GUP_FLAGS_IGNORE_VMA_PERMISSIONS);
240         int ignore_sigkill = !!(flags & GUP_FLAGS_IGNORE_SIGKILL);
241
242         if (len <= 0)
243                 return 0;
244         /* 
245          * Require read or write permissions.
246          * If 'force' is set, we only require the "MAY" flags.
247          */
248         vm_flags  = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
249         vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
250         i = 0;
251
252         do {
253                 struct vm_area_struct *vma;
254                 unsigned int foll_flags;
255
256                 //vma = find_extend_vma(mm, start);
257                 vma = find_vma(mm, start);
258                 if (!vma && in_gate_area(tsk, start)) {
259                         unsigned long pg = start & PAGE_MASK;
260                         struct vm_area_struct *gate_vma = get_gate_vma(tsk);
261                         pgd_t *pgd;
262                         pud_t *pud;
263                         pmd_t *pmd;
264                         pte_t *pte;
265
266                         /* user gate pages are read-only */
267                         if (!ignore && write)
268                                 return i ? : -EFAULT;
269                         if (pg > TASK_SIZE)
270                                 pgd = pgd_offset_k(pg);
271                         else
272                                 pgd = pgd_offset_gate(mm, pg);
273                         BUG_ON(pgd_none(*pgd));
274                         pud = pud_offset(pgd, pg);
275                         BUG_ON(pud_none(*pud));
276                         pmd = pmd_offset(pud, pg);
277                         if (pmd_none(*pmd))
278                                 return i ? : -EFAULT;
279                         pte = pte_offset_map(pmd, pg);
280                         if (pte_none(*pte)) {
281                                 pte_unmap(pte);
282                                 return i ? : -EFAULT;
283                         }
284                         if (pages) {
285                                 struct page *page = vm_normal_page(gate_vma, start, *pte);
286                                 pages[i] = page;
287                                 if (page)
288                                         get_page(page);
289                         }
290                         pte_unmap(pte);
291                         if (vmas)
292                                 vmas[i] = gate_vma;
293                         i++;
294                         start += PAGE_SIZE;
295                         len--;
296                         continue;
297                 }
298
299                 if (!vma ||
300                     (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
301                     (!ignore && !(vm_flags & vma->vm_flags)))
302                         return i ? : -EFAULT;
303
304                 if (is_vm_hugetlb_page(vma)) {
305 #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
306                         i = follow_hugetlb_page(mm, vma, pages, vmas,
307                                                 &start, &len, i);
308 #else
309                         i = follow_hugetlb_page(mm, vma, pages, vmas,
310                                                 &start, &len, i, write);
311 #endif
312                         continue;
313                 }
314
315                 foll_flags = FOLL_TOUCH;
316                 if (pages)
317                         foll_flags |= FOLL_GET;
318
319 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
320 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30)
321                 if (!write && use_zero_page(vma))
322                   foll_flags |= FOLL_ANON;
323 #endif
324 #endif
325
326                 do {
327                         struct page *page;
328
329 #if 0
330                         /*
331                          * If we have a pending SIGKILL, don't keep faulting
332                          * pages and potentially allocating memory, unless
333                          * current is handling munlock--e.g., on exit. In
334                          * that case, we are not allocating memory.  Rather,
335                          * we're only unlocking already resident/mapped pages.
336                          */
337                         if (unlikely(!ignore_sigkill &&
338                                         fatal_signal_pending(current)))
339                                 return i ? i : -ERESTARTSYS;
340 #endif
341
342                         if (write)
343                                 foll_flags |= FOLL_WRITE;
344
345                         
346                         //cond_resched();
347
348                         DBPRINTF ("pages = %p vma = %p\n", pages, vma);
349                         while (!(page = follow_page(vma, start, foll_flags))) {
350                                 int ret;
351                                 ret = handle_mm_fault(mm, vma, start,
352                                                 foll_flags & FOLL_WRITE);
353
354 #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
355                                 if (ret & VM_FAULT_WRITE)
356                                   foll_flags &= ~FOLL_WRITE;
357                                 
358                                 switch (ret & ~VM_FAULT_WRITE) {
359                                 case VM_FAULT_MINOR:
360                                   tsk->min_flt++;
361                                   break;
362                                 case VM_FAULT_MAJOR:
363                                   tsk->maj_flt++;
364                                   break;
365                                 case VM_FAULT_SIGBUS:
366                                   return i ? i : -EFAULT;
367                                 case VM_FAULT_OOM:
368                                   return i ? i : -ENOMEM;
369                                 default:
370                                   BUG();
371                                 }
372                                 
373 #else
374                                 if (ret & VM_FAULT_ERROR) {
375                                   if (ret & VM_FAULT_OOM)
376                                     return i ? i : -ENOMEM;
377                                   else if (ret & VM_FAULT_SIGBUS)
378                                     return i ? i : -EFAULT;
379                                   BUG();
380                                 }
381                                 if (ret & VM_FAULT_MAJOR)
382                                   tsk->maj_flt++;
383                                 else
384                                   tsk->min_flt++;
385                                 
386                                 /*
387                                  * The VM_FAULT_WRITE bit tells us that
388                                  * do_wp_page has broken COW when necessary,
389                                  * even if maybe_mkwrite decided not to set
390                                  * pte_write. We can thus safely do subsequent
391                                  * page lookups as if they were reads. But only
392                                  * do so when looping for pte_write is futile:
393                                  * in some cases userspace may also be wanting
394                                  * to write to the gotten user page, which a
395                                  * read fault here might prevent (a readonly
396                                  * page might get reCOWed by userspace write).
397                                  */
398                                 if ((ret & VM_FAULT_WRITE) &&
399                                     !(vma->vm_flags & VM_WRITE))
400                                   foll_flags &= ~FOLL_WRITE;
401                                 
402                                 //cond_resched();
403 #endif
404                                 
405                         }
406
407                         if (IS_ERR(page))
408                                 return i ? i : PTR_ERR(page);
409                         if (pages) {
410                                 pages[i] = page;
411
412 #if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
413                                 flush_anon_page(page, start);
414 #else
415                                 flush_anon_page(vma, page, start);
416 #endif
417                                 flush_dcache_page(page);
418                         }
419                         if (vmas)
420                                 vmas[i] = vma;
421                         i++;
422                         start += PAGE_SIZE;
423                         len--;
424                 } while (len && start < vma->vm_end);
425         } while (len);
426         return i;
427 }
428 #endif
429
430
431 int get_user_pages_uprobe(struct task_struct *tsk, struct mm_struct *mm,
432                 unsigned long start, int len, int write, int force,
433                 struct page **pages, struct vm_area_struct **vmas)
434 {
435 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
436         int flags = 0;
437
438         if (write)
439                 flags |= GUP_FLAGS_WRITE;
440         if (force)
441                 flags |= GUP_FLAGS_FORCE;
442
443         return __get_user_pages_uprobe(tsk, mm,
444                                 start, len, flags,
445                                 pages, vmas);
446 #else
447         return get_user_pages(tsk, mm, start, len, write, force, pages, vmas);
448 #endif
449 }
450
451
452 int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
453 {
454         struct mm_struct *mm;
455         struct vm_area_struct *vma;
456         void *old_buf = buf;
457         unsigned long addr1 = addr;
458         unsigned int* inst_buf = (unsigned int*)old_buf;
459
460
461         mm = get_task_mm(tsk);
462         if (!mm)
463                 return 0;
464
465         down_read(&mm->mmap_sem);
466         /* ignore errors, just check how much was successfully transferred */
467         while (len) {
468                 int bytes, ret, offset;
469                 void *maddr;
470                 struct page *page = NULL;
471
472                 ret = get_user_pages_uprobe(tsk, mm, addr, 1,
473                                 write, 1, &page, &vma);
474
475                 if (ret <= 0) {
476                         /*
477                          * Check if this is a VM_IO | VM_PFNMAP VMA, which
478                          * we can access using slightly different code.
479                          */
480 #ifdef CONFIG_HAVE_IOREMAP_PROT
481                         vma = find_vma(mm, addr);
482                         if (!vma)
483                                 break;
484                         if (vma->vm_ops && vma->vm_ops->access)
485                                 ret = vma->vm_ops->access(vma, addr, buf,
486                                                           len, write);
487                         if (ret <= 0)
488 #endif
489                                 break;
490                         bytes = ret;
491                 } else {
492                         bytes = len;
493                         offset = addr & (PAGE_SIZE-1);
494                         if (bytes > PAGE_SIZE-offset)
495                                 bytes = PAGE_SIZE-offset;
496
497                         maddr = kmap(page);
498                         if (write) {
499                                 copy_to_user_page(vma, page, addr,
500                                                   maddr + offset, buf, bytes);
501                                 set_page_dirty_lock(page);
502                         } else {
503                                 copy_from_user_page(vma, page, addr,
504                                                     buf, maddr + offset, bytes);
505                         }
506                         kunmap(page);
507                         page_cache_release(page);
508                 }
509                 len -= bytes;
510                 buf += bytes;
511                 addr += bytes;
512         }
513         up_read(&mm->mmap_sem);
514         mmput(mm);
515
516         return buf - old_buf;
517 }
518
519 int page_present (struct mm_struct *mm, unsigned long address)
520 {
521         pgd_t *pgd;
522         pud_t *pud;
523         pmd_t *pmd;
524         pte_t *ptep, pte;
525         unsigned long pfn;
526
527         pgd = pgd_offset(mm, address);
528         if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
529                 goto out;
530
531         pud = pud_offset(pgd, address);
532         if (pud_none(*pud) || unlikely(pud_bad(*pud)))
533                 goto out;
534
535         pmd = pmd_offset(pud, address);
536         if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
537                 goto out;
538
539         ptep = pte_offset_map(pmd, address);
540         if (!ptep)
541                 goto out;
542
543         pte = *ptep;
544         pte_unmap(ptep);
545         if (pte_present(pte)) {
546                 pfn = pte_pfn(pte);
547                 if (pfn_valid(pfn)) {
548                         return 1;
549                 }
550         }
551
552 out:
553         return 0;
554 }
555
556
557 EXPORT_SYMBOL_GPL (page_present);
558 EXPORT_SYMBOL_GPL (get_user_pages_uprobe);
559 EXPORT_SYMBOL_GPL (access_process_vm_atomic);
560