1 ////////////////////////////////////////////////////////////////////////////////////
3 // FILE: us_proc_inst.c
6 // This file is C source for SWAP driver.
8 // SEE ALSO: us_proc_inst.h
9 // AUTHOR: A.Gerenkov, E. Gorelkina
10 // COMPANY NAME: Samsung Research Center in Moscow
11 // DEPT NAME: Advanced Software Group
12 // CREATED: 2008.06.02
14 // REVISION DATE: 2008.12.02
16 ////////////////////////////////////////////////////////////////////////////////////
19 #include "us_proc_inst.h"
21 #include "../kprobe/dbi_kprobes_deps.h"
22 #include "../kprobe/dbi_uprobes.h"
24 #include "sspt/sspt.h"
25 #include "java_inst.h"
27 #define mm_read_lock(task, mm, atomic, lock) \
28 mm = atomic ? task->active_mm : get_task_mm(task); \
31 panic("ERRR mm_read_lock: mm == NULL\n"); \
35 lock = down_read_trylock(&mm->mmap_sem); \
38 down_read(&mm->mmap_sem); \
41 #define mm_read_unlock(mm, atomic, lock) \
43 up_read(&mm->mmap_sem); \
50 DEFINE_PER_CPU (us_proc_vtp_t *, gpVtp) = NULL;
51 DEFINE_PER_CPU (struct pt_regs *, gpCurVtpRegs) = NULL;
53 #if defined(CONFIG_MIPS)
54 # define ARCH_REG_VAL(regs, idx) regs->regs[idx]
55 #elif defined(CONFIG_ARM)
56 # define ARCH_REG_VAL(regs, idx) regs->uregs[idx]
58 # define ARCH_REG_VAL(regs, idx) 0
59 # warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
62 unsigned long ujprobe_event_pre_handler (struct us_ip *ip, struct pt_regs *regs);
63 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6);
64 int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
66 static int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic);
67 static int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int no_rp2);
71 LIST_HEAD(proc_probes_list);
74 struct dentry *launchpad_daemon_dentry = NULL;
75 EXPORT_SYMBOL_GPL(launchpad_daemon_dentry);
79 unsigned long android_app_vma_start = 0;
80 unsigned long android_app_vma_end = 0;
81 struct dentry *app_process_dentry = NULL;
82 #endif /* ANDROID_APP */
85 #define print_event(fmt, args...) \
88 sprintf(buf, fmt, ##args); \
89 pack_event_info(US_PROBE_ID, RECORD_ENTRY, "ds", 0x0badc0de, buf); \
92 static inline int is_libonly(void)
94 return !strcmp(us_proc_info.path,"*");
97 // is user-space instrumentation
98 static inline int is_us_instrumentation(void)
100 return !!us_proc_info.path;
103 struct sspt_procs *get_proc_probes_by_task(struct task_struct *task)
105 struct sspt_procs *procs, *tmp;
108 if (task != current) {
109 printk("ERROR get_proc_probes_by_task: \'task != current\'\n");
113 return us_proc_info.pp;
116 list_for_each_entry_safe(procs, tmp, &proc_probes_list, list) {
117 if (procs->tgid == task->tgid) {
125 void add_proc_probes(struct task_struct *task, struct sspt_procs *procs)
127 list_add_tail(&procs->list, &proc_probes_list);
130 struct sspt_procs *get_proc_probes_by_task_or_new(struct task_struct *task)
132 struct sspt_procs *procs = get_proc_probes_by_task(task);
134 procs = sspt_procs_copy(us_proc_info.pp, task);
135 add_proc_probes(task, procs);
142 static int is_slp_app_with_dentry(struct vm_area_struct *vma,
143 struct dentry *dentry)
145 struct vm_area_struct *slp_app_vma = NULL;
147 if (vma->vm_file->f_dentry == launchpad_daemon_dentry) {
149 while (slp_app_vma) {
150 if (slp_app_vma->vm_file) {
151 if (slp_app_vma->vm_file->f_dentry == dentry &&
152 slp_app_vma->vm_pgoff == 0) {
156 slp_app_vma = slp_app_vma->vm_next;
165 static int is_android_app_with_dentry(struct vm_area_struct *vma,
166 struct dentry *dentry)
168 struct vm_area_struct *android_app_vma = NULL;
170 if (vma->vm_file->f_dentry == app_process_dentry) {
171 android_app_vma = vma;
172 while (android_app_vma) {
173 if (android_app_vma->vm_file) {
174 if (android_app_vma->vm_file->f_dentry == dentry) {
175 android_app_vma_start = android_app_vma->vm_start;
176 android_app_vma_end = android_app_vma->vm_end;
180 android_app_vma = android_app_vma->vm_next;
186 #endif /* ANDROID_APP */
188 struct dentry *dentry_by_path(const char *path)
190 struct dentry *dentry;
191 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
193 if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
194 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
196 if (path_lookup(path, LOOKUP_FOLLOW, &nd) != 0) {
197 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
198 EPRINTF("failed to lookup dentry for path %s!", path);
202 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
205 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
206 dentry = nd.path.dentry;
208 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
209 dentry = st_path.dentry;
211 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
215 static int find_task_by_path (const char *path, struct task_struct **p_task, struct list_head *tids)
218 struct task_struct *task;
219 struct vm_area_struct *vma;
220 struct mm_struct *mm;
221 struct dentry *dentry = dentry_by_path(path);
225 /* find corresponding dir entry, this is also check for valid path */
226 // TODO: test - try to instrument process with non-existing path
227 // TODO: test - try to instrument process with existing path and delete file just after start
228 if (dentry == NULL) {
233 for_each_process (task) {
235 if ( 0 != inst_pid && ( inst_pid != task->pid ) )
238 mm = get_task_mm(task);
243 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
244 if (vma->vm_file->f_dentry == dentry) {
247 get_task_struct (task);
253 if (is_slp_app_with_dentry(vma, dentry)) {
255 get_task_struct(task);
261 if (is_android_app_with_dentry(vma, dentry)) {
263 get_task_struct(task);
266 #endif /* ANDROID_APP */
270 // only decrement usage count on mm since we cannot sleep here
271 atomic_dec(&mm->mm_users);
278 DPRINTF ("found pid %d for %s.", (*p_task)->pid, path);
279 *p_task = (*p_task)->group_leader;
280 gl_nNotifyTgid = (*p_task)->tgid;
282 DPRINTF ("pid for %s not found!", path);
289 static void us_vtp_event_pre_handler (us_proc_vtp_t * vtp, struct pt_regs *regs)
291 __get_cpu_var(gpVtp) = vtp;
292 __get_cpu_var(gpCurVtpRegs) = regs;
295 static void us_vtp_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
297 us_proc_vtp_t *vtp = __get_cpu_var(gpVtp);
298 #if !defined(CONFIG_X86)
299 struct pt_regs *regs = __get_cpu_var(gpCurVtpRegs);
305 us_proc_vtp_data_t *vtp_data;
311 list_for_each_entry_rcu (vtp_data, &vtp->list, list) {
312 // DPRINTF ("[%d]proc %s(%d): %lx", nCount++, current->comm, current->pid, vtp->addr);
313 fmt[1] = vtp_data->type;
314 if (vtp_data->reg == -1)
315 vaddr = vtp_data->off;
317 vaddr = ARCH_REG_VAL (regs, vtp_data->reg) + vtp_data->off;
318 // DPRINTF ("VTP type '%c'", vtp_data->type);
319 switch (vtp_data->type)
324 if (read_proc_vm_atomic (current, vaddr, &ival, sizeof (ival)) < sizeof (ival))
325 EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
327 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, ival, vtp_data->name);
330 if (read_proc_vm_atomic (current, vaddr, &ival, sizeof (ival)) < sizeof (ival))
331 EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
333 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, ival, vtp_data->name);
336 if (read_proc_vm_atomic (current, vaddr, &cval, sizeof (cval)) < sizeof (cval))
337 EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
339 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, cval, vtp_data->name);
342 if (current->active_mm) {
344 struct vm_area_struct *vma;
347 if (get_user_pages_atomic (current, current->active_mm, vaddr, 1, 0, 1, &page, &vma) <= 0) {
348 EPRINTF ("get_user_pages_atomic failed for proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
351 maddr = kmap_atomic (page, KM_USER0);
352 len = strlen (maddr + (vaddr & ~PAGE_MASK));
353 sval = kmalloc (len + 1, GFP_KERNEL);
355 EPRINTF ("failed to alloc memory for string in proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
357 copy_from_user_page (vma, page, vaddr, sval, maddr + (vaddr & ~PAGE_MASK), len + 1);
358 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, sval, vtp_data->name);
361 kunmap_atomic (maddr, KM_USER0);
362 page_cache_release (page);
365 EPRINTF ("task %s/%u has no mm!", current->comm, current->pid);
368 EPRINTF ("unknown variable type '%c'", vtp_data->type);
371 dbi_uprobe_return ();
374 static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_inst_info, int atomic)
376 struct vm_area_struct *vma;
379 unsigned int old_ips_count, old_vtps_count;
380 struct task_struct *t;
381 struct mm_struct *mm;
383 mm = atomic ? task->active_mm : get_task_mm (task);
385 return task_inst_info->unres_ips_count + task_inst_info->unres_vtps_count;
387 old_ips_count = task_inst_info->unres_ips_count;
388 old_vtps_count = task_inst_info->unres_vtps_count;
390 down_read (&mm->mmap_sem);
393 // skip non-text section
395 if (vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || !vma->vm_file || (vma->vm_flags & VM_ACCOUNT) ||
396 !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
397 !(vma->vm_flags & (VM_READ | VM_MAYREAD))) {
399 if (vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || !vma->vm_file) {
405 * After process was forked, some time it inherits parent process environment.
406 * We need to renew instrumentation when we detect that process gets own environment.
408 for (i = 0; i < task_inst_info->libs_count; i++) {
409 // struct path tmp_path;
410 // tmp_path.dentry = task_inst_info->p_libs[i].m_f_dentry;
411 // tmp_path.mnt = task_inst_info->p_libs[i].m_vfs_mount;
412 // char* p_path = d_path ( &tmp_path, path_buffer, 255 );
413 // DPRINTF("f_dentry:%x m_f_dentry:%x path:%s", vma->vm_file->f_dentry,
414 // task_inst_info->p_libs[i].m_f_dentry, p_path );
416 //TODO: test - try to instrument non-existing libs
417 if (vma->vm_file->f_dentry == task_inst_info->p_libs[i].m_f_dentry) {
418 // DPRINTF("vm_flags:%x loaded:%x ips_count:%d vtps_count:%d",
419 // vma->vm_flags, task_inst_info->p_libs[i].loaded,
420 // task_inst_info->p_libs[i].ips_count, task_inst_info->p_libs[i].vtps_count );
421 if (!task_inst_info->p_libs[i].loaded) {
422 // DPRINTF("!VM_EXECUTABLE && !loaded");
424 int app_flag = (vma->vm_file->f_dentry == task_inst_info->m_f_dentry);
425 DPRINTF ("post dyn lib event %s/%s", current->comm, task_inst_info->p_libs[i].path);
426 // if we installed something, post library info for those IPs
427 p = strrchr(task_inst_info->p_libs[i].path, '/');
429 p = task_inst_info->p_libs[i].path;
432 task_inst_info->p_libs[i].loaded = 1;
433 task_inst_info->p_libs[i].vma_start = vma->vm_start;
434 task_inst_info->p_libs[i].vma_end = vma->vm_end;
435 task_inst_info->p_libs[i].vma_flag = vma->vm_flags;
436 pack_event_info (DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
437 task->tgid, p, vma->vm_start, vma->vm_end-vma->vm_start, app_flag);
439 for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++) {
440 DPRINTF("ips_count current:%d", k);
441 if (!task_inst_info->p_libs[i].p_ips[k].installed) {
442 DPRINTF("!installed");
443 addr = task_inst_info->p_libs[i].p_ips[k].offset;
444 addr += vma->vm_start;
445 if (page_present (mm, addr)) {
446 DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.",
447 task->pid, task_inst_info->p_libs[i].path,
448 task_inst_info->p_libs[i].p_ips[k].offset, addr);
449 task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
450 task_inst_info->p_libs[i].p_ips[k].retprobe.kp.addr = (kprobe_opcode_t *) addr;
451 task_inst_info->unres_ips_count--;
452 err = register_usprobe(task, &task_inst_info->p_libs[i].p_ips[k], atomic);
454 DPRINTF ("failed to install IP at %lx/%p. Error %d!",
455 task_inst_info->p_libs[i].p_ips[k].offset,
456 task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
461 for (k = 0; k < task_inst_info->p_libs[i].vtps_count; k++) {
462 DPRINTF("vtps_count current:%d", k);
463 if (!task_inst_info->p_libs[i].p_vtps[k].installed) {
464 DPRINTF("!installed");
465 addr = task_inst_info->p_libs[i].p_vtps[k].addr;
466 if (!(vma->vm_flags & VM_EXECUTABLE))
467 addr += vma->vm_start;
468 if (page_present (mm, addr)) {
469 DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.",
470 task->pid, task_inst_info->p_libs[i].path,
471 task_inst_info->p_libs[i].p_ips[k].offset, addr);
472 task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.tgid = task_inst_info->tgid;
473 task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
474 task_inst_info->p_libs[i].p_vtps[k].jprobe.entry = (kprobe_opcode_t *) us_vtp_event_handler;
475 task_inst_info->p_libs[i].p_vtps[k].jprobe.pre_entry = (kprobe_pre_entry_handler_t) us_vtp_event_pre_handler;
476 task_inst_info->p_libs[i].p_vtps[k].jprobe.priv_arg = &task_inst_info->p_libs[i].p_vtps[k];
477 task_inst_info->p_libs[i].p_vtps[k].installed = 1;
478 task_inst_info->unres_vtps_count--;
479 err = dbi_register_ujprobe(task, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
481 EPRINTF ("failed to install VTP at %p. Error %d!",
482 task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr, err);
494 up_read (&mm->mmap_sem);
497 return task_inst_info->unres_ips_count + task_inst_info->unres_vtps_count;
500 static void set_mapping_file(struct sspt_file *file,
501 const struct sspt_procs *procs,
502 const struct task_struct *task,
503 const struct vm_area_struct *vma);
505 int install_otg_ip(unsigned long addr,
506 kprobe_pre_entry_handler_t pre_handler,
507 unsigned long jp_handler,
508 kretprobe_handler_t rp_handler)
511 struct task_struct *task = current->group_leader;
512 struct mm_struct *mm = task->mm;
515 struct vm_area_struct *vma = find_vma(mm, addr);
516 if (vma && (vma->vm_flags & VM_EXEC) &&
517 vma->vm_file && vma->vm_file->f_dentry) {
518 unsigned long offset_addr = addr - vma->vm_start;
519 struct dentry *dentry = vma->vm_file->f_dentry;
520 char *name = dentry->d_iname;
521 struct sspt_procs *procs = get_proc_probes_by_task(task);
522 struct ip_data pd = {
523 .offset = offset_addr,
524 .pre_handler = pre_handler,
525 .jp_handler = jp_handler,
526 .rp_handler = rp_handler,
530 struct sspt_file *file = sspt_procs_find_file_or_new(procs, dentry, name);
531 struct sspt_page *page = sspt_get_page(file, offset_addr);
532 struct us_ip *ip = sspt_find_ip(page, offset_addr & ~PAGE_MASK);
535 set_mapping_file(file, procs, task, vma);
540 // TODO: sspt_procs_find_file_or_new --> sspt_procs_find_file ?!
541 struct sspt_file *file = sspt_procs_find_file_or_new(procs, dentry, name);
542 sspt_file_add_ip(file, &pd);
544 /* if addr mapping, that probe install, else it be installed in do_page_fault handler */
545 if (page_present(mm, addr)) {
546 ip = sspt_find_ip(page, offset_addr & ~PAGE_MASK);
547 sspt_set_ip_addr(ip, page, file);
550 ret = register_usprobe_my(task, ip);
552 sspt_page_installed(page);
554 printk("ERROR install_otg_ip: ret=%d\n", ret);
565 EXPORT_SYMBOL_GPL(install_otg_ip);
568 static int uninstall_mapped_ips (struct task_struct *task, inst_us_proc_t* task_inst_info, int atomic)
572 for (i = 0; i < task_inst_info->libs_count; i++)
574 DPRINTF ("clear lib %s.", task_inst_info->p_libs[i].path);
575 for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++)
577 if (task_inst_info->p_libs[i].p_ips[k].installed)
579 DPRINTF ("remove IP at %p.", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr);
580 err = unregister_usprobe (task, &task_inst_info->p_libs[i].p_ips[k], atomic, 0);
583 EPRINTF ("failed to uninstall IP at %p. Error %d!", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
586 task_inst_info->unres_ips_count++;
589 for (k = 0; k < task_inst_info->p_libs[i].vtps_count; k++)
591 if (task_inst_info->p_libs[i].p_vtps[k].installed)
593 dbi_unregister_ujprobe (task, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
594 task_inst_info->unres_vtps_count++;
595 task_inst_info->p_libs[i].p_vtps[k].installed = 0;
598 task_inst_info->p_libs[i].loaded = 0;
601 DPRINTF ("Ures IPs %d.", task_inst_info->unres_ips_count);
602 DPRINTF ("Ures VTPs %d.", task_inst_info->unres_vtps_count);
606 static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
608 kernel_probe_t *probe = NULL;
610 if (probes_flags & kflag) {
611 probe = find_probe(addr);
613 iRet = remove_probe_from_list (addr);
615 EPRINTF ("remove_probe_from_list(0x%lx) result=%d!", addr, iRet);
619 probes_flags &= ~kflag;
621 if (us_proc_probes & uflag) {
622 if (!(probes_flags & uflag)) {
624 iRet = unregister_kernel_probe(probe);
626 EPRINTF ("unregister_kernel_probe(0x%lx) result=%d!",
632 us_proc_probes &= ~uflag;
637 static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag);
639 int deinst_usr_space_proc (void)
641 int iRet = 0, found = 0;
642 struct task_struct *task = 0;
643 inst_us_proc_t *task_inst_info = NULL;
645 if (!is_us_instrumentation()) {
649 iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
652 EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
654 iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
657 EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
659 iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
662 EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
664 iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
667 EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
669 iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
672 EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
675 struct sspt_procs *procs;
677 for_each_process(task) {
678 procs = get_proc_probes_by_task(task);
680 int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
682 EPRINTF ("failed to uninstall IPs (%d)!", ret);
685 dbi_unregister_all_uprobes(task, 1);
691 if (us_proc_info.tgid == 0)
694 for_each_process (task)
696 if (task->tgid == us_proc_info.tgid)
699 get_task_struct (task);
708 ret = uninstall_us_proc_probes(task, us_proc_info.pp, US_UNREGS_PROBE);
710 EPRINTF ("failed to uninstall IPs %d!", ret);
713 put_task_struct (task);
715 printk("### 1 ### dbi_unregister_all_uprobes:\n");
716 dbi_unregister_all_uprobes(task, 1);
717 us_proc_info.tgid = 0;
718 for(i = 0; i < us_proc_info.libs_count; i++)
719 us_proc_info.p_libs[i].loaded = 0;
725 static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
727 kernel_probe_t *probe = NULL;
730 DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
731 "probes_flags = 0x%x, kflag = 0x%x",
732 us_proc_probes, uflag, probes_flags, kflag);
734 if (!(probes_flags & kflag)) {
735 iRet = add_probe_to_list (addr, &probe);
737 EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
740 probes_flags |= kflag;
742 if (!(us_proc_probes & uflag)) {
743 if (!(probes_flags & uflag)) {
744 iRet = register_kernel_probe (probe);
746 EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
750 us_proc_probes |= uflag;
759 static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic);
761 int inst_usr_space_proc (void)
764 struct task_struct *task = 0;
766 if (!is_us_instrumentation()) {
770 DPRINTF("User space instr");
773 launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
774 if (launchpad_daemon_dentry == NULL) {
781 app_process_dentry = dentry_by_path("/system/bin/app_process");
782 if (app_process_dentry == NULL) {
786 android_app_vma_start = 0;
787 android_app_vma_end = 0;
788 #endif /* ANDROID_APP */
790 for (i = 0; i < us_proc_info.libs_count; i++) {
791 us_proc_info.p_libs[i].loaded = 0;
793 /* check whether process is already running
794 * 1) if process is running - look for the libraries in the process maps
795 * 1.1) check if page for symbol does exist
796 * 1.1.1) if page exists - instrument it
797 * 1.1.2) if page does not exist - make sure that do_page_fault handler is installed
798 * 2) if process is not running - make sure that do_page_fault handler is installed
803 // FIXME: clear_task_inst_info();
804 for_each_process (task) {
805 struct sspt_procs *procs;
807 if (task->flags & PF_KTHREAD){
808 DPRINTF("ignored kernel thread %d\n",
813 procs = get_proc_probes_by_task_or_new(task);
814 DPRINTF("trying process");
815 install_proc_probes(task, procs, 1);
816 //put_task_struct (task);
821 ret = find_task_by_path (us_proc_info.path, &task, NULL);
824 DPRINTF("task found. installing probes");
825 us_proc_info.tgid = task->pid;
826 install_proc_probes(task, us_proc_info.pp, 0);
827 put_task_struct (task);
831 // enable 'do_page_fault' probe to detect when they will be loaded
832 ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
835 EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
838 // enable 'do_exit' probe to detect for remove task_struct
839 ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
842 EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
845 /* enable 'copy_process' */
846 ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
849 EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
853 // enable 'mm_release' probe to detect when for remove user space probes
854 ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
857 EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
861 // enable 'do_munmap' probe to detect when for remove user space probes
862 ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
865 EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
871 #include "../../tools/gpmu/probes/entry_data.h"
873 extern storage_arg_t sa_dpf;
875 void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
877 struct task_struct *task = current->group_leader;
879 if (task->flags & PF_KTHREAD) {
880 DPRINTF("ignored kernel thread %d\n", task->pid);
884 if (is_us_instrumentation()) {
885 swap_put_entry_data((void *)addr, &sa_dpf);
888 EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
891 unsigned long imi_sum_time = 0;
892 unsigned long imi_sum_hit = 0;
893 EXPORT_SYMBOL_GPL (imi_sum_time);
894 EXPORT_SYMBOL_GPL (imi_sum_hit);
896 static void set_mapping_file(struct sspt_file *file,
897 const struct sspt_procs *procs,
898 const struct task_struct *task,
899 const struct vm_area_struct *vma)
901 int app_flag = (vma->vm_file->f_dentry == procs->dentry);
903 file->vm_start = vma->vm_start;
904 file->vm_end = vma->vm_end;
906 pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
907 task->tgid, file->name, vma->vm_start,
908 vma->vm_end - vma->vm_start, app_flag);
911 void print_vma(struct mm_struct *mm);
913 static int register_us_page_probe(struct sspt_page *page,
914 const struct sspt_file *file,
915 const struct task_struct *task)
920 spin_lock(&page->lock);
922 if (sspt_page_is_install(page)) {
923 printk("page %x in %s task[tgid=%u, pid=%u] already installed\n",
924 page->offset, file->dentry->d_iname, task->tgid, task->pid);
929 sspt_page_assert_install(page);
930 sspt_set_all_ip_addr(page, file);
932 list_for_each_entry(ip, &page->ip_list, list) {
933 err = register_usprobe_my(task, ip);
940 sspt_page_installed(page);
942 spin_unlock(&page->lock);
947 static int unregister_us_page_probe(const struct task_struct *task,
948 struct sspt_page *page, enum US_FLAGS flag)
953 spin_lock(&page->lock);
954 if (!sspt_page_is_install(page)) {
955 spin_unlock(&page->lock);
959 list_for_each_entry(ip, &page->ip_list, list) {
960 err = unregister_usprobe_my(task, ip, flag);
967 if (flag != US_DISARM) {
968 sspt_page_uninstalled(page);
970 spin_unlock(&page->lock);
975 static int check_vma(struct vm_area_struct *vma)
978 return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
979 !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
980 !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
982 return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC));
987 static void install_page_probes(unsigned long page_addr, struct task_struct *task, struct sspt_procs *procs, int atomic)
990 struct mm_struct *mm;
991 struct vm_area_struct *vma;
993 mm_read_lock(task, mm, atomic, lock);
995 vma = find_vma(mm, page_addr);
996 if (vma && check_vma(vma)) {
997 struct dentry *dentry = vma->vm_file->f_dentry;
998 struct sspt_file *file = sspt_procs_find_file(procs, dentry);
1000 struct page_probes *page;
1001 if (!file->loaded) {
1002 set_mapping_file(file, procs, task, vma);
1006 page = sspt_find_page_mapped(file, page_addr);
1008 register_us_page_probe(page, file, task);
1013 mm_read_unlock(mm, atomic, lock);
1016 static void install_file_probes(struct task_struct *task, struct mm_struct *mm, struct sspt_file *file)
1018 struct sspt_page *page = NULL;
1019 struct hlist_node *node = NULL;
1020 struct hlist_head *head = NULL;
1021 int i, table_size = (1 << file->page_probes_hash_bits);
1023 for (i = 0; i < table_size; ++i) {
1024 head = &file->page_probes_table[i];
1025 hlist_for_each_entry_rcu(page, node, head, hlist) {
1026 if (page_present(mm, page->offset)) {
1027 register_us_page_probe(page, file, task);
1033 static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic)
1036 struct vm_area_struct *vma;
1037 struct mm_struct *mm;
1039 mm_read_lock(task, mm, atomic, lock);
1041 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1042 if (check_vma(vma)) {
1043 struct dentry *dentry = vma->vm_file->f_dentry;
1044 struct sspt_file *file = sspt_procs_find_file(procs, dentry);
1046 if (!file->loaded) {
1047 set_mapping_file(file, procs, task, vma);
1051 install_file_probes(task, mm, file);
1056 mm_read_unlock(mm, atomic, lock);
1059 static int check_install_pages_in_file(struct task_struct *task, struct sspt_file *file)
1062 int table_size = (1 << file->page_probes_hash_bits);
1063 struct sspt_page *page;
1064 struct hlist_node *node, *tmp;
1065 struct hlist_head *head;
1067 for (i = 0; i < table_size; ++i) {
1068 head = &file->page_probes_table[i];
1069 hlist_for_each_entry_safe (page, node, tmp, head, hlist) {
1070 if (page->install) {
1079 static int unregister_us_file_probes(struct task_struct *task, struct sspt_file *file, enum US_FLAGS flag)
1082 int table_size = (1 << file->page_probes_hash_bits);
1083 struct sspt_page *page;
1084 struct hlist_node *node, *tmp;
1085 struct hlist_head *head;
1087 for (i = 0; i < table_size; ++i) {
1088 head = &file->page_probes_table[i];
1089 hlist_for_each_entry_safe (page, node, tmp, head, hlist) {
1090 err = unregister_us_page_probe(task, page, flag);
1098 if (flag != US_DISARM) {
1105 static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag)
1108 struct sspt_file *file;
1110 list_for_each_entry_rcu(file, &procs->file_list, list) {
1111 err = unregister_us_file_probes(task, file, flag);
1121 static pid_t find_proc_by_task(const struct task_struct *task, const struct dentry *dentry)
1123 struct vm_area_struct *vma;
1124 struct mm_struct *mm = task->active_mm;
1129 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1130 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
1131 if (vma->vm_file->f_dentry == dentry) {
1135 if (is_slp_app_with_dentry(vma, dentry)) {
1138 #endif /* SLP_APP */
1140 if (is_android_app_with_dentry(vma, dentry)) {
1143 #endif /* ANDROID_APP */
1150 void do_page_fault_ret_pre_code (void)
1152 struct task_struct *task = current->group_leader;
1153 struct mm_struct *mm = task->mm;
1154 struct vm_area_struct *vma = 0;
1155 struct sspt_procs *procs = NULL;
1157 * Because process threads have same address space
1158 * we instrument only group_leader of all this threads
1160 unsigned long addr = 0;
1164 struct timeval imi_tv1;
1165 struct timeval imi_tv2;
1166 #define USEC_IN_SEC_NUM 1000000
1168 if (task->flags & PF_KTHREAD) {
1169 DPRINTF("ignored kernel thread %d\n", task->pid);
1173 if (!is_us_instrumentation()) {
1177 addr = (unsigned long)swap_get_entry_data(&sa_dpf);
1180 printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
1187 valid_addr = mm && page_present(mm, addr);
1193 procs = get_proc_probes_by_task_or_new(task);
1196 if (us_proc_info.tgid == 0) {
1197 pid_t tgid = find_proc_by_task(task, us_proc_info.m_f_dentry);
1199 us_proc_info.tgid = gl_nNotifyTgid = tgid;
1203 if (us_proc_info.tgid == task->tgid) {
1204 procs = us_proc_info.pp;
1209 unsigned long page = addr & PAGE_MASK;
1212 do_gettimeofday(&imi_tv1);
1213 install_page_probes(page, task, procs, 1);
1214 do_gettimeofday(&imi_tv2);
1216 imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) * USEC_IN_SEC_NUM +
1217 (imi_tv2.tv_usec - imi_tv1.tv_usec));
1221 EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
1224 void do_exit_probe_pre_code (void)
1226 // TODO: remove task
1228 EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
1230 int check_vma_area(struct vm_area_struct *vma, unsigned long start, unsigned long end)
1232 return (vma->vm_start >= start && vma->vm_end <= end);
1235 void print_vma(struct mm_struct *mm)
1237 struct vm_area_struct *vma;
1238 printk("### print_vma: START\n");\
1239 printk("### print_vma: START\n");
1241 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1242 char *x = vma->vm_flags & VM_EXEC ? "x" : "-";
1243 char *r = vma->vm_flags & VM_READ ? "r" : "-";
1244 char *w = vma->vm_flags & VM_WRITE ? "w" : "-";
1245 char *name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : "N/A";
1247 printk("### [%8x..%8x] %s%s%s pgoff=\'%8u\' %s\n",
1248 vma->vm_start, vma->vm_end, x, r, w, vma->vm_pgoff, name);
1250 printk("### print_vma: END\n");
1253 static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *procs, unsigned long start, size_t len)
1255 struct mm_struct *mm = task->mm;
1256 struct vm_area_struct *vma;
1257 unsigned long end, pointer, step;
1259 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
1263 if ((len = PAGE_ALIGN(len)) == 0) {
1267 vma = find_vma(mm, start);
1268 if (vma && check_vma(vma)) {
1269 struct sspt_file *file;
1270 unsigned long end = start + len;
1271 struct dentry *dentry = vma->vm_file->f_dentry;
1273 file = sspt_procs_find_file(procs, dentry);
1275 if (vma->vm_start == start || vma->vm_end == end) {
1276 unregister_us_file_probes(task, file, US_NOT_RP2);
1279 unsigned long page_addr;
1280 struct sspt_page *page;
1282 for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
1283 page = sspt_find_page_mapped(file, page_addr);
1285 unregister_us_page_probe(task, page, US_NOT_RP2);
1289 if (check_install_pages_in_file(task, file)) {
1299 void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
1301 struct sspt_procs *procs = NULL;
1302 struct task_struct *task = current;
1304 //if user-space instrumentation is not set
1305 if (!is_us_instrumentation()) {
1310 procs = get_proc_probes_by_task(task);
1312 if (task->tgid == us_proc_info.tgid) {
1313 procs = us_proc_info.pp;
1318 if (remove_unmap_probes(task, procs, start, len)) {
1319 printk("ERROR do_munmap: start=%x, len=%x\n", start, len);
1323 EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
1325 void mm_release_probe_pre_code(void)
1327 struct task_struct *task = current;
1328 struct sspt_procs *procs = NULL;
1330 if (!is_us_instrumentation() || task->tgid != task->pid) {
1335 procs = get_proc_probes_by_task(task);
1337 if (task->tgid == us_proc_info.tgid) {
1338 procs = get_proc_probes_by_task(task);
1339 us_proc_info.tgid = 0;
1344 int ret = uninstall_us_proc_probes(task, procs, US_NOT_RP2);
1346 EPRINTF ("failed to uninstall IPs (%d)!", ret);
1349 dbi_unregister_all_uprobes(task, 1);
1352 EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
1355 static void recover_child(struct task_struct *child_task, struct sspt_procs *procs)
1357 uninstall_us_proc_probes(child_task, procs, US_DISARM);
1360 static void rm_uprobes_child(struct task_struct *new_task)
1363 struct sspt_procs *procs = get_proc_probes_by_task(current);
1365 recover_child(new_task, procs);
1368 if(us_proc_info.tgid == current->tgid) {
1369 recover_child(new_task, us_proc_info.pp);
1374 void copy_process_ret_pre_code(struct task_struct *p)
1379 if(p->mm != current->mm) // check flags CLONE_VM
1380 rm_uprobes_child(p);
1384 DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
1385 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
1386 DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
1387 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
1390 unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
1392 __get_cpu_var (gpCurIp) = ip;
1393 __get_cpu_var (gpUserRegs) = regs;
1397 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
1399 struct us_ip *ip = __get_cpu_var(gpCurIp);
1400 unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1403 struct pt_regs *regs = __get_cpu_var(gpUserRegs);
1404 if (is_java_inst_enabled() && handle_java_event(regs)) {
1407 #endif /* __ANDROID */
1410 #if defined(CONFIG_ARM)
1411 if (ip->offset & 0x01)
1413 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr | 0x01, arg1, arg2, arg3, arg4, arg5, arg6);
1415 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1418 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1420 // Mr_Nobody: uncomment for valencia
1421 //unregister_usprobe(current, ip, 1);
1422 dbi_uprobe_return ();
1425 void send_plt(struct us_ip *ip)
1427 unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1428 struct vm_area_struct *vma = find_vma(current->mm, addr);
1430 if (vma && check_vma(vma)) {
1432 unsigned long real_addr;
1433 unsigned long real_got = vma->vm_flags & VM_EXECUTABLE ?
1435 ip->got_addr + vma->vm_start;
1437 if (!read_proc_vm_atomic(current, real_got, &real_addr, sizeof(real_addr))) {
1438 printk("Failed to read got %p at memory address %p!\n", ip->got_addr, real_got);
1442 vma = find_vma(current->mm, real_addr);
1443 if (vma && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
1444 name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : NULL;
1446 printk("Failed to get vma, includes %x address\n", real_addr);
1451 pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp", addr, real_addr, name, real_addr - vma->vm_start);
1453 pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppp", addr, real_addr, real_addr - vma->vm_start);
1458 int uretprobe_event_handler(struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
1460 int retval = regs_return_value(regs);
1461 unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1463 if (ip->got_addr && ip->flag_got == 0) {
1468 #if defined(CONFIG_ARM)
1469 if (ip->offset & 0x01)
1471 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr | 0x01, retval);
1473 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1476 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1478 // Mr_Nobody: uncomment for valencia
1479 //unregister_usprobe(current, ip, 1);
1483 static int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
1486 ip->jprobe.kp.tgid = task->tgid;
1488 if (ip->jprobe.entry == NULL) {
1489 ip->jprobe.entry = (kprobe_opcode_t *)ujprobe_event_handler;
1490 DPRINTF("Set default event handler for %x\n", ip->offset);
1493 if (ip->jprobe.pre_entry == NULL) {
1494 ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
1495 DPRINTF("Set default pre handler for %x\n", ip->offset);
1498 ip->jprobe.priv_arg = ip;
1499 ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
1501 DPRINTF ("dbi_register_ujprobe() failure %d", ret);
1505 if (ip->flag_retprobe) {
1506 // Mr_Nobody: comment for valencia
1507 ip->retprobe.kp.tgid = task->tgid;
1508 if (ip->retprobe.handler == NULL) {
1509 ip->retprobe.handler = (kretprobe_handler_t)uretprobe_event_handler;
1510 DPRINTF("Set default ret event handler for %x\n", ip->offset);
1513 ip->retprobe.priv_arg = ip;
1514 ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
1516 EPRINTF ("dbi_register_uretprobe() failure %d", ret);
1524 static int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int not_rp2)
1526 dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
1528 if (ip->flag_retprobe) {
1529 dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
1535 unsigned long get_stack_size(struct task_struct *task,
1536 struct pt_regs *regs)
1538 #ifdef CONFIG_ADD_THREAD_STACK_INFO
1539 return (task->stack_start - dbi_get_stack_ptr(regs));
1541 struct vm_area_struct *vma = NULL;
1542 struct mm_struct *mm = NULL;
1543 unsigned long result = 0;
1544 int atomic = in_atomic();
1546 mm = (atomic ? task->active_mm: get_task_mm(task));
1550 down_read(&mm->mmap_sem);
1552 vma = find_vma(mm, dbi_get_stack_ptr(regs));
1555 result = vma->vm_end - dbi_get_stack_ptr(regs);
1560 up_read(&mm->mmap_sem);
1568 EXPORT_SYMBOL_GPL(get_stack_size);
1570 unsigned long get_stack(struct task_struct *task, struct pt_regs *regs,
1571 char *buf, unsigned long sz)
1573 unsigned long stack_sz = get_stack_size(task, regs);
1574 unsigned long real_sz = (stack_sz > sz ? sz: stack_sz);
1575 int res = read_proc_vm_atomic(task, dbi_get_stack_ptr(regs), buf, real_sz);
1578 EXPORT_SYMBOL_GPL(get_stack);
1580 int dump_to_trace(probe_id_t probe_id, void *addr, const char *buf,
1583 unsigned long rest_sz = sz;
1584 const char *data = buf;
1586 while (rest_sz >= EVENT_MAX_SIZE) {
1587 pack_event_info(probe_id, RECORD_ENTRY, "pa",
1588 addr, EVENT_MAX_SIZE, data);
1589 rest_sz -= EVENT_MAX_SIZE;
1590 data += EVENT_MAX_SIZE;
1594 pack_event_info(probe_id, RECORD_ENTRY, "pa", addr, rest_sz, data);
1598 EXPORT_SYMBOL_GPL(dump_to_trace);
1600 int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
1601 void *addr, struct pt_regs *regs, unsigned long sz)
1603 unsigned long real_sz = 0;
1606 buf = (char *)kmalloc(sz, GFP_ATOMIC);
1609 real_sz = get_stack(task, regs, buf, sz);
1611 dump_to_trace(probe_id, addr, buf, real_sz);
1618 EXPORT_SYMBOL_GPL(dump_backtrace);
1620 unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
1622 unsigned long retaddr = 0;
1623 struct hlist_node *item, *tmp_node;
1624 struct kretprobe_instance *ri;
1627 hlist_for_each_safe (item, tmp_node, &ip->retprobe.used_instances) {
1628 ri = hlist_entry (item, struct kretprobe_instance, uflist);
1630 if (ri->task && ri->task->pid == task->pid &&
1631 ri->task->tgid == task->tgid)
1632 retaddr = (unsigned long)ri->ret_addr;
1639 return dbi_get_ret_addr(task_pt_regs(task));
1641 EXPORT_SYMBOL_GPL(get_ret_addr);