1 ////////////////////////////////////////////////////////////////////////////////////
3 // FILE: us_proc_inst.c
6 // This file is C source for SWAP driver.
8 // SEE ALSO: us_proc_inst.h
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"
25 static int register_usprobe (struct task_struct *task, struct mm_struct *mm, us_proc_ip_t * ip, int atomic, kprobe_opcode_t * islot);
26 static int unregister_usprobe (struct task_struct *task, us_proc_ip_t * ip, int atomic);
31 find_task_by_path (const char *path, struct task_struct **p_task, struct list_head *tids)
34 struct task_struct *task;
35 struct vm_area_struct *vma;
38 //fp_kallsyms_lookup_name_t fp;
42 /* find corresponding dir entry, this is also check for valid path */
43 // TODO: test - try to instrument process with non-existing path
44 // TODO: test - try to instrument process with existing path and delete file just after start
45 if (path_lookup (path, LOOKUP_FOLLOW, &nd) != 0)
47 EPRINTF ("failed to lookup dentry for path %s!", path);
52 for_each_process (task) {
53 mm = get_task_mm (task);
56 down_read (&mm->mmap_sem);
59 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
60 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
61 if (vma->vm_file->f_dentry == nd.dentry) {
63 if (vma->vm_file->f_dentry == nd.path.dentry) {
67 get_task_struct (task);
74 up_read (&mm->mmap_sem);
83 DPRINTF ("found pid %d for %s.", (*p_task)->pid, path);
84 gl_nNotifyTgid = current->tgid;
88 DPRINTF ("pid for %s not found!", path);
91 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
99 #if defined(CONFIG_MIPS)
100 # define ARCH_REG_VAL(regs, idx) regs->regs[idx]
101 #elif defined(CONFIG_ARM)
102 # define ARCH_REG_VAL(regs, idx) regs->uregs[idx]
104 # define ARCH_REG_VAL(regs, idx) 0
105 # warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
108 DEFINE_PER_CPU (us_proc_vtp_t *, gpVtp) = NULL;
109 //EXPORT_PER_CPU_SYMBOL_GPL(gpVtp);
110 DEFINE_PER_CPU (struct pt_regs *, gpCurVtpRegs) = NULL;
111 //EXPORT_PER_CPU_SYMBOL_GPL(gpCurVtpRegs);
114 us_vtp_event_pre_handler (us_proc_vtp_t * vtp, struct pt_regs *regs)
116 __get_cpu_var(gpVtp) = vtp;
117 __get_cpu_var(gpCurVtpRegs) = regs;
121 us_vtp_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
124 us_proc_vtp_t *vtp = __get_cpu_var(gpVtp);
125 #if !defined(CONFIG_X86)
126 struct pt_regs *regs = __get_cpu_var(gpCurVtpRegs);
133 //struct list_head *pos, *tmp;
134 us_proc_vtp_data_t *vtp_data;
139 list_for_each_entry_rcu (vtp_data, &vtp->list, list)
141 // DPRINTF ("[%d]proc %s(%d): %lx", nCount++, current->comm, current->pid, vtp->addr);
142 fmt[1] = vtp_data->type;
143 if (vtp_data->reg == -1)
144 vaddr = vtp_data->off;
146 vaddr = ARCH_REG_VAL (regs, vtp_data->reg) + vtp_data->off;
147 // DPRINTF ("VTP type '%c'", vtp_data->type);
148 switch (vtp_data->type)
153 if (read_proc_vm_atomic (current, vaddr, &ival, sizeof (ival)) < sizeof (ival))
154 EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
156 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, ival);
159 if (read_proc_vm_atomic (current, vaddr, &ival, sizeof (ival)) < sizeof (ival))
160 EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
162 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, ival);
165 if (read_proc_vm_atomic (current, vaddr, &cval, sizeof (cval)) < sizeof (cval))
166 EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
168 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, cval);
171 if (current->active_mm)
174 struct vm_area_struct *vma;
177 if (get_user_pages_atomic (current, current->active_mm, vaddr, 1, 0, 1, &page, &vma) <= 0)
179 EPRINTF ("get_user_pages_atomic failed for proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
182 maddr = kmap_atomic (page, KM_USER0);
183 len = strlen (maddr + (vaddr & ~PAGE_MASK));
184 sval = kmalloc (len + 1, GFP_KERNEL);
186 EPRINTF ("failed to alloc memory for string in proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
189 copy_from_user_page (vma, page, vaddr, sval, maddr + (vaddr & ~PAGE_MASK), len + 1);
190 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, sval);
193 kunmap_atomic (maddr, KM_USER0);
194 page_cache_release (page);
197 EPRINTF ("task %s/%u has no mm!", current->comm, current->pid);
200 EPRINTF ("unknown variable type '%c'", vtp_data->type);
207 install_mapped_ips (struct task_struct *task, int atomic)
209 struct vm_area_struct *vma;
210 int i, k, err, retry;
211 unsigned long addr;//, slot_idx;
212 //char lib_path[256];
213 //static unsigned npcdep;
214 unsigned int old_ips_count, old_vtps_count;
215 struct mm_struct *mm;
217 struct list_head plist;
222 struct list_head plist;
228 mm = atomic ? task->active_mm : get_task_mm (task);
230 // DPRINTF ("proc %d has no mm", task->pid);
231 return us_proc_info.unres_ips_count + us_proc_info.unres_vtps_count;
234 old_ips_count = us_proc_info.unres_ips_count;
235 old_vtps_count = us_proc_info.unres_vtps_count;
237 down_read (&mm->mmap_sem);
241 // skip non-text section
242 if (!(vma->vm_flags & VM_EXEC) || !vma->vm_file || (vma->vm_flags & VM_ACCOUNT) ||
243 !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
244 !(vma->vm_flags & (VM_READ | VM_MAYREAD)))
249 //DPRINTF("check mapped lib %s at %lx.",
250 // d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, lib_path, sizeof(lib_path)), vma->vm_start);
252 for (i = 0; i < us_proc_info.libs_count; i++)
254 //DPRINTF("lookup lib %s.", us_proc_info.p_libs[i].path);
255 //TODO: test - try to instrument non-existing libs
256 if (vma->vm_file->f_dentry == us_proc_info.p_libs[i].m_f_dentry)
258 //if (strcmp(d_path(vma->vm_file->m_f_dentry, vma->vm_file->f_vfsmnt, lib_path, sizeof(lib_path)),
259 // us_proc_info.p_libs[i].path) == 0){
260 //DPRINTF("found lib %s.", us_proc_info.p_libs[i].path);
261 //unsigned oi_count = us_proc_info.unres_ips_count;
262 //unsigned ov_count = us_proc_info.unres_vtps_count;
263 for (k = 0; k < us_proc_info.p_libs[i].ips_count; k++/*, slot_idx++*/)
265 if (!us_proc_info.p_libs[i].p_ips[k].installed)
267 addr = us_proc_info.p_libs[i].p_ips[k].offset;
268 if (!(vma->vm_flags & VM_EXECUTABLE))
269 addr += vma->vm_start;
270 //DPRINTF("check sym %s at %lx.", us_proc_info.p_libs[i].p_ips[k].name, addr);
271 if (page_present (mm, addr))
273 //DPRINTF ("pid %d, %s sym is present at %lx/%lx.", task->pid, us_proc_info.p_libs[i].path, us_proc_info.p_libs[i].p_ips[k].offset, addr);
274 //if (!us_proc_info.p_libs[i].p_ips[k].installed)
276 us_proc_info.unres_ips_count--;
277 us_proc_info.p_libs[i].p_ips[k].installed = 1;
278 DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.", task->pid, us_proc_info.p_libs[i].path, us_proc_info.p_libs[i].p_ips[k].offset, addr);
279 nip = kmalloc(sizeof(struct ip_node), GFP_KERNEL);
281 EPRINTF ("failed to allocate list item for IP!");
284 us_proc_info.p_libs[i].p_ips[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
285 us_proc_info.p_libs[i].p_ips[k].retprobe.kp.addr = (kprobe_opcode_t *) addr;
286 INIT_LIST_HEAD (&nip->plist);
287 nip->ip = &us_proc_info.p_libs[i].p_ips[k];
288 list_add_tail (&nip->plist, &iplist);
293 for (k = 0; k < us_proc_info.p_libs[i].vtps_count; k++/*, slot_idx++*/)
295 if (us_proc_info.p_libs[i].p_vtps[k].installed)
297 /*DPRINTF("VTPs at %lx are already installed.",
298 us_proc_info.p_libs[i].p_ips[k].offset); */
302 addr = us_proc_info.p_libs[i].p_vtps[k].addr;
303 if (!(vma->vm_flags & VM_EXECUTABLE))
304 addr += vma->vm_start;
305 //DPRINTF("check VTPs at %lx.", addr);
306 if (page_present (mm, addr))
308 //us_proc_vtp_data_t *vtp_data;
309 //DPRINTF("VTPs is loaded at %lx.", addr);
310 us_proc_info.unres_vtps_count--;
311 us_proc_info.p_libs[i].p_vtps[k].installed = 1;
312 /*list_for_each_entry_rcu (vtp_data, &us_proc_info.p_libs[i].p_vtps[k].list, list)
314 DPRINTF ("VTP %s is loaded at %lx.", vtp_data->name, addr);
316 us_proc_info.p_libs[i].p_vtps[k].jprobe.kp.tgid = us_proc_info.tgid;
317 us_proc_info.p_libs[i].p_vtps[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
318 us_proc_info.p_libs[i].p_vtps[k].jprobe.entry = (kprobe_opcode_t *) us_vtp_event_handler;
319 us_proc_info.p_libs[i].p_vtps[k].jprobe.pre_entry = (kprobe_pre_entry_handler_t) us_vtp_event_pre_handler;
320 us_proc_info.p_libs[i].p_vtps[k].jprobe.priv_arg = &us_proc_info.p_libs[i].p_vtps[k];
321 nvtp = kmalloc(sizeof(struct vtp_node), GFP_KERNEL);
323 EPRINTF ("failed to allocate list item for VTP!");
326 INIT_LIST_HEAD (&nvtp->plist);
327 nvtp->vtp = &us_proc_info.p_libs[i].p_vtps[k];
328 list_add_tail (&nvtp->plist, &vtplist);
332 if(!(vma->vm_flags & VM_EXECUTABLE) && !us_proc_info.p_libs[i].loaded
333 /*((oi_count != us_proc_info.unres_ips_count) || (ov_count != us_proc_info.unres_vtps_count))*/){
335 // DPRINTF ("post dyn lib event %s", us_proc_info.p_libs[i].path);
336 // if we installed something, post library info for those IPs
337 p = strrchr(us_proc_info.p_libs[i].path, '/');
339 p = us_proc_info.p_libs[i].path;
342 us_proc_info.p_libs[i].loaded = 1;
343 pack_event_info (DYN_LIB_PROBE_ID, RECORD_ENTRY, "spd",
344 p, vma->vm_start, vma->vm_end-vma->vm_start);
351 up_read (&mm->mmap_sem);
355 if(!list_empty(&iplist) || !list_empty(&vtplist)){
356 // DPRINTF ("Unres IPs/VTPs %d/%d -> %d/%d.", old_ips_count, old_vtps_count,
357 // us_proc_info.unres_ips_count, us_proc_info.unres_vtps_count);
361 list_for_each_entry_safe(nip, tnip, &iplist, plist) {
362 // DPRINTF ("Install %p/%d IP at %lx.", task, task->pid, nip->ip->offset);
363 if((PAGE_SIZE-(nip->ip->offset % PAGE_SIZE)) < MAX_INSN_SIZE){
365 // DPRINTF ("Possibly 1st insn of IP at %lx lies on 2 pages.", nip->ip->offset);
367 err = register_usprobe (task, mm, nip->ip, atomic, 0);
369 EPRINTF ("failed to install IP at %lx/%p. Error %d!", nip->ip->offset, nip->ip->jprobe.kp.addr, err);
370 list_del(&nip->plist);
373 list_for_each_entry_safe(nvtp, tnvtp, &vtplist, plist) {
374 // DPRINTF ("Install VTP at %p.", nvtp->vtp->jprobe.kp.addr);
375 if((PAGE_SIZE-(nvtp->vtp->addr % PAGE_SIZE)) < MAX_INSN_SIZE){
377 // DPRINTF ("Possibly 1st insn of VTP %lx lies on 2 pages.", nvtp->vtp->addr);
379 err = register_ujprobe (task, mm, &nvtp->vtp->jprobe, atomic);
381 EPRINTF ("failed to install VTP at %p. Error %d!", nvtp->vtp->jprobe.kp.addr, err);
382 list_del(&nvtp->plist);
386 if(retry) goto _restart;
388 return us_proc_info.unres_ips_count + us_proc_info.unres_vtps_count;
392 uninstall_mapped_ips (struct task_struct *task, int atomic)
396 for (i = 0; i < us_proc_info.libs_count; i++)
398 // DPRINTF ("clear lib %s.", us_proc_info.p_libs[i].path);
399 for (k = 0; k < us_proc_info.p_libs[i].ips_count; k++)
401 if (us_proc_info.p_libs[i].p_ips[k].installed)
403 // DPRINTF ("remove IP at %p.", us_proc_info.p_libs[i].p_ips[k].jprobe.kp.addr);
404 err = unregister_usprobe (task, &us_proc_info.p_libs[i].p_ips[k], atomic);
407 EPRINTF ("failed to uninstall IP at %p. Error %d!", us_proc_info.p_libs[i].p_ips[k].jprobe.kp.addr, err);
410 us_proc_info.unres_ips_count++;
411 us_proc_info.p_libs[i].p_ips[k].installed = 0;
414 for (k = 0; k < us_proc_info.p_libs[i].vtps_count; k++)
416 if (us_proc_info.p_libs[i].p_vtps[k].installed)
418 //us_proc_vtp_data_t *vtp_data;
419 /*list_for_each_entry_rcu (vtp_data, &us_proc_info.p_libs[i].p_vtps[k].list, list)
421 DPRINTF ("remove VTP %s.", vtp_data->name);
423 unregister_ujprobe (task, &us_proc_info.p_libs[i].p_vtps[k].jprobe, atomic);
424 us_proc_info.unres_vtps_count++;
425 us_proc_info.p_libs[i].p_vtps[k].installed = 0;
429 // DPRINTF ("Ures IPs %d.", us_proc_info.unres_ips_count);
430 // DPRINTF ("Ures VTPs %d.", us_proc_info.unres_vtps_count);
436 send_sig_jprobe_event_handler (int sig, struct siginfo *info, struct task_struct *t, struct sigpending *signals)
439 struct task_struct *task;
441 //DPRINTF("send_signal[%d] %d proc %d", nCount++, sig, t->pid);
443 //DPRINTF("%s(%d) send_signal %d for target proc %s(%d)", current->comm, current->pid, sig, t->comm, t->pid);
447 if (t->tgid != us_proc_info.tgid)
451 // look for another process with the same tgid
453 for_each_process (task)
455 if ((task->pid != t->pid) && (task->tgid == us_proc_info.tgid))
464 // DPRINTF ("%s(%d) send_signal SIGKILL for the last target proc %s(%d)", current->comm, current->pid, t->comm, t->pid);
465 iRet = uninstall_mapped_ips (t, 1);
467 EPRINTF ("failed to uninstall IPs (%d)!", iRet);
472 uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
474 kernel_probe_t *probe = NULL;
477 if (probes_flags & kflag) {
478 probe = find_probe(addr);
480 iRet = remove_probe_from_list (addr);
482 EPRINTF ("remove_probe_from_list(0x%lx) result=%d!", addr, iRet);
486 probes_flags &= ~kflag;
489 if (us_proc_probes & uflag) {
490 if (!(probes_flags & uflag)) {
492 iRet = unregister_kernel_probe(probe);
494 EPRINTF ("unregister_kernel_probe(0x%lx) result=%d!",
500 us_proc_probes &= ~uflag;
507 deinst_usr_space_proc (void)
509 int iRet = 0, found = 0;
510 struct task_struct *task = 0;
512 iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
515 EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
517 iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
520 EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
522 if (us_proc_info.tgid == 0)
526 for_each_process (task)
528 if (task->tgid == us_proc_info.tgid)
531 get_task_struct (task);
540 iRet = uninstall_mapped_ips (task, 0);
542 EPRINTF ("failed to uninstall IPs %d!", iRet);
543 put_task_struct (task);
544 unregister_all_uprobes(task, 1);
545 us_proc_info.tgid = 0;
546 for(i = 0; i < us_proc_info.libs_count; i++)
547 us_proc_info.p_libs[i].loaded = 0;
554 install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
556 kernel_probe_t *probe = NULL;
559 DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
560 "probes_flags = 0x%x, kflag = 0x%x",
561 us_proc_probes, uflag, probes_flags, kflag);
563 if (!(probes_flags & kflag)) {
564 iRet = add_probe_to_list (addr, &probe);
566 EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
569 probes_flags |= kflag;
572 if (!(us_proc_probes & uflag)) {
573 if (!(probes_flags & uflag)) {
574 iRet = register_kernel_probe (probe);
576 EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
580 us_proc_probes |= uflag;
590 inst_usr_space_proc (void)
593 struct task_struct *task = 0;
594 //struct mm_struct *mm;
596 if (!us_proc_info.path)
599 for (i = 0; i < us_proc_info.libs_count; i++)
600 us_proc_info.p_libs[i].loaded = 0;
601 /* check whether process is already running
602 * 1) if process is running - look for the libraries in the process maps
603 * 1.1) check if page for symbol does exist
604 * 1.1.1) if page exists - instrument it
605 * 1.1.2) if page does not exist - make sure that do_page_fault handler is installed
606 * 2) if process is not running - make sure that do_page_fault handler is installed
609 find_task_by_path (us_proc_info.path, &task, NULL);
615 us_proc_info.tgid = task->pid;
616 /*mm = get_task_mm (task);
619 EPRINTF ("task %d has no mm!", task->pid);
622 down_read (&mm->mmap_sem);*/
623 install_mapped_ips (task, 0);
624 //up_read (&mm->mmap_sem);
626 put_task_struct (task);
629 // enable 'do_page_fault' probe to detect when they will be loaded
630 iRet = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
633 EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", iRet);
636 // enable 'do_exit' probe to detect when user proc exits in order to remove user space probes
637 iRet = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
640 EPRINTF ("install_kernel_probe(do_exit) result=%d!", iRet);
650 do_page_fault_ret_pre_code (void)
652 struct mm_struct *mm;
653 struct vm_area_struct *vma = 0;
655 if (!us_proc_info.path)
658 if (!strcmp(us_proc_info.path,"*"))
660 //DPRINTF("us_proc_info.path = * ALL");
661 if (install_mapped_ips (current, 1) == 0)
663 /*iRet = unregister_one_probe(pf_probe_id);
665 EPRINTF("unregister_one_probe(do_page_fault) result=%d!", iRet); */
670 //DPRINTF("do_page_fault from proc %d-%d-%d", current->pid, us_proc_info.tgid, us_proc_info.unres_ips_count);
671 if ((us_proc_info.unres_ips_count + us_proc_info.unres_vtps_count) == 0)
673 //DPRINTF("do_page_fault: there no unresolved IPs");
677 if (us_proc_info.tgid == 0)
679 //DPRINTF("do_page_fault check proc %d", current->pid);
681 /*if( path_lookup(us_proc_info.path, LOOKUP_FOLLOW, &nd) != 0 ) {
682 EPRINTF("failed to lookup dentry for path %s!", us_proc_info.path);
685 mm = get_task_mm (current);//current->active_mm;
688 down_read (&mm->mmap_sem);
689 //BUG_ON(down_read_trylock(&mm->mmap_sem) == 0);
693 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
695 /*struct path pth = {.dentry=vma->vm_file->f_dentry, .mnt=vma->vm_file->f_vfsmnt};
696 DPRINTF("do_page_fault: dentry %p-%p.", vma->vm_file->f_dentry, us_proc_info.m_f_dentry);
697 DPRINTF("do_page_fault: expath %s.",
698 d_path(&pth, expath, sizeof(expath)-1));*/
699 if (vma->vm_file->f_dentry == us_proc_info.m_f_dentry)
701 //if (strcmp(d_path(vma->vm_file->m_f_dentry, vma->vm_file->f_vfsmnt, expath, sizeof(expath)),
702 // us_proc_info.path) == 0){
703 //DPRINTF("do_page_fault: found!");
710 up_read (&mm->mmap_sem);
713 // DPRINTF ("proc %s/%d has no mm", current->comm, current->pid);
718 DPRINTF ("do_page_fault found target proc %s(%d)", current->comm, current->pid);
719 us_proc_info.tgid = current->pid;
720 gl_nNotifyTgid = current->tgid;
723 if (us_proc_info.tgid == current->tgid)
725 //DPRINTF("do_page_fault from target proc %d", us_proc_info.tgid);
726 if (install_mapped_ips (current, 1) == 0)
728 /*iRet = unregister_one_probe(pf_probe_id);
730 EPRINTF("unregister_one_probe(do_page_fault) result=%d!", iRet); */
734 //DPRINTF("do_page_fault from proc %d-%d exit", current->pid, us_proc_info.pid);
736 EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
739 do_exit_probe_pre_code (void)
742 struct task_struct *task;
744 //DPRINTF("do_exit from proc %s-%d", current->comm, current->pid);
746 if (current->tgid != us_proc_info.tgid)
749 //DPRINTF("exit target proc %s-%d", current->comm, current->pid);
751 // look for another process with the same tgid
753 for_each_process (task)
755 //if(task->tgid == us_proc_info.tgid)
756 // DPRINTF("check proc %s-%d", task->comm, task->pid);
757 if ((task->pid != current->pid) && (task->tgid == us_proc_info.tgid))
767 // DPRINTF ("do_exit from the last target proc %s-%d", current->comm, current->pid);
768 iRet = uninstall_mapped_ips (current, 1);
770 EPRINTF ("failed to uninstall IPs (%d)!", iRet);
771 unregister_all_uprobes(current, 1);
772 us_proc_info.tgid = 0;
773 for(i = 0; i < us_proc_info.libs_count; i++)
774 us_proc_info.p_libs[i].loaded = 0;
778 EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
780 DEFINE_PER_CPU (us_proc_ip_t *, gpCurIp) = NULL;
781 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
782 DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
783 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
785 // XXX MCPP: introduced custom default handlers defined in (exported from) another kernel module(s)
786 unsigned long (* ujprobe_event_pre_handler_custom_p)(us_proc_ip_t *, struct pt_regs *) = NULL;
787 EXPORT_SYMBOL(ujprobe_event_pre_handler_custom_p);
788 void (* ujprobe_event_handler_custom_p)() = NULL;
789 EXPORT_SYMBOL(ujprobe_event_handler_custom_p);
790 int (* uretprobe_event_handler_custom_p)(struct kretprobe_instance *, struct pt_regs *, us_proc_ip_t *) = NULL;
791 EXPORT_SYMBOL(uretprobe_event_handler_custom_p);
794 ujprobe_event_pre_handler (us_proc_ip_t * ip, struct pt_regs *regs)
796 __get_cpu_var (gpCurIp) = ip;
797 __get_cpu_var (gpUserRegs) = regs;
802 ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
804 us_proc_ip_t *ip = __get_cpu_var (gpCurIp);
808 //DPRINTF("[%d]proc %s(%d): ENTRY %s(%#lx)", nCount++, current->comm, current->pid, ip->name, arg1);
809 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", ip->jprobe.kp.addr, arg1, arg2, arg3, arg4, arg5, arg6);
814 uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, us_proc_ip_t * ip)
818 int retval = regs_return_value(regs);
819 //DPRINTF("[%d]proc %s(%d): RETURN %s(%d)", nCount++, current->comm, current->pid, ip->name, retval);
820 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", ip->retprobe.kp.addr, retval);
825 register_usprobe (struct task_struct *task, struct mm_struct *mm, us_proc_ip_t * ip, int atomic, kprobe_opcode_t * islot)
829 ip->jprobe.kp.tgid = task->tgid;
830 //ip->jprobe.kp.addr = (kprobe_opcode_t *) addr;
831 if(!ip->jprobe.entry) {
832 if (ujprobe_event_handler_custom_p != NULL)
833 ip->jprobe.entry = (kprobe_opcode_t *) ujprobe_event_handler_custom_p;
835 ip->jprobe.entry = (kprobe_opcode_t *) ujprobe_event_handler;
836 //DPRINTF("Failed custom ujprobe_event_handler_custom_p");
839 if(!ip->jprobe.pre_entry) {
840 if (ujprobe_event_pre_handler_custom_p != NULL)
841 ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t) ujprobe_event_pre_handler_custom_p;
843 ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t) ujprobe_event_pre_handler;
844 //DPRINTF("Failed custom ujprobe_event_pre_handler_custom_p");
847 ip->jprobe.priv_arg = ip;
848 ret = register_ujprobe (task, mm, &ip->jprobe, atomic);
851 EPRINTF ("register_ujprobe() failure %d", ret);
855 //DPRINTF("IP %s boostable = %d", ip->name, ip->jprobe.kp.ainsn.boostable);
856 #if 0//defined(CONFIG_X86)
857 // _start is an entry point of the program, so when control reaches it
858 // return address is not saved on stack and can not be hijacked,
859 // so we can not set retprobe on it
860 if(strcmp(ip->name, "_start")!=0)
863 ip->retprobe.kp.tgid = task->tgid;
864 //ip->retprobe.kp.addr = (kprobe_opcode_t *) addr;
865 if(!ip->retprobe.handler) {
866 if (uretprobe_event_handler_custom_p != NULL)
867 ip->retprobe.handler = (kretprobe_handler_t) uretprobe_event_handler_custom_p;
869 ip->retprobe.handler = (kretprobe_handler_t) uretprobe_event_handler;
870 //DPRINTF("Failed custom uretprobe_event_handler_custom_p");
873 ip->retprobe.priv_arg = ip;
874 ret = register_uretprobe (task, mm, &ip->retprobe, atomic);
877 EPRINTF ("register_uretprobe() failure %d", ret);
886 unregister_usprobe (struct task_struct *task, us_proc_ip_t * ip, int atomic)
888 unregister_ujprobe (task, &ip->jprobe, atomic);
889 #if 0//defined(CONFIG_X86)
890 // _start is an entry point of the program, so when control reaches it
891 // return address is not saved on stack and can not be hijacked,
892 // so we can not set retprobe on it
893 if(strcmp(ip->name, "_start")!=0)
895 unregister_uretprobe (task, &ip->retprobe, atomic);