[FIX] Fix wrong probe disarming in userspace (case with lr in regs)
authorDmitry Kovalenko <d.kovalenko@samsung.com>
Thu, 1 Aug 2013 09:46:01 +0000 (13:46 +0400)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Thu, 1 Aug 2013 09:46:01 +0000 (13:46 +0400)
driver/storage.c
driver/us_proc_inst.c
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/dbi_uprobes.c

index c7d82a8..59e9c26 100644 (file)
@@ -602,11 +602,9 @@ void unlink_bundle(void)
                kfree ((void *) us_proc_info.p_libs);
                us_proc_info.p_libs = NULL;
        }
-       /* if (path) */
-       /* { */
-       /*      kfree ((void *) path); */
-       /*      //putname(path); */
-       /* } */
+       if (path) {
+               kfree ((void *) path);
+       }
 
        us_proc_info.tgid = 0;
 }
@@ -692,9 +690,14 @@ int link_bundle(void)
        {
                int lib_path_len;
                char *lib_path;
-
-               us_proc_info.path = (char *)p;
+               us_proc_info.path = kmalloc(len, GFP_KERNEL);
+               if (!us_proc_info.path) {
+                       DPRINTF("Can't allocate memory for us_proc_info.path");
+                       return -1;
+               }
+               us_proc_info.path = strcpy(us_proc_info.path, (char *)p);
                DPRINTF("app path = %s", us_proc_info.path);
+               printk("app path = %s\n", us_proc_info.path);
                p += len;
 
                if (strcmp(us_proc_info.path, "*")) {
index 77642ea..db564c0 100644 (file)
@@ -411,26 +411,6 @@ int deinst_usr_space_proc (void)
        if (iRet)
                EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
 
-       iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
-                       0, &cp_probe);
-       if (iRet)
-               EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
-
-        iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
-                        0, &mr_probe);
-        if (iRet)
-                EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
-
-       iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
-                       0, &exit_probe);
-       if (iRet)
-               EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
-
-       iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
-                       0, &unmap_probe);
-       if (iRet)
-               EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
-
        if (is_libonly()) {
                struct sspt_proc *proc;
 
@@ -448,38 +428,61 @@ int deinst_usr_space_proc (void)
        }
        else
        {
-               if (us_proc_info.tgid == 0)
-                       return 0;
+               if (us_proc_info.tgid != 0) {
                        rcu_read_lock ();
-               for_each_process (task)
-               {
-                       if (task->tgid == us_proc_info.tgid)
+                       for_each_process (task)
                        {
-                               found = 1;
-                               get_task_struct (task);
-                               break;
-                       }
-               }
-               rcu_read_unlock ();
-               if (found)
-               {
-                       int i, ret;
-                       // uninstall IPs
-                       ret = uninstall_us_proc_probes(task, us_proc_info.pp, US_UNREGS_PROBE);
-                       if (ret != 0) {
-                               EPRINTF ("failed to uninstall IPs %d!", ret);
+                               if (task->tgid == us_proc_info.tgid)
+                               {
+                                       found = 1;
+                                       get_task_struct (task);
+                                       break;
+                               }
                        }
+                       rcu_read_unlock ();
+                       if (found)
+                       {
+                               int i, ret;
+                               // uninstall IPs
+                               ret = uninstall_us_proc_probes(task,
+                                                              us_proc_info.pp,
+                                                              US_UNREGS_PROBE);
+                               if (ret != 0) {
+                                       EPRINTF ("failed to uninstall IPs %d!",
+                                                ret);
+                               }
 
-                       put_task_struct (task);
+                               put_task_struct (task);
 
-                       printk("### 1 ### dbi_unregister_all_uprobes:\n");
-                       dbi_unregister_all_uprobes(task, 1);
-                       us_proc_info.tgid = 0;
-                       for(i = 0; i < us_proc_info.libs_count; i++)
-                               us_proc_info.p_libs[i].loaded = 0;
+                               printk("###1### dbi_unregister_all_uprobes:\n");
+                               dbi_unregister_all_uprobes(task, 1);
+                               us_proc_info.tgid = 0;
+                               for(i = 0; i < us_proc_info.libs_count; i++)
+                                       us_proc_info.p_libs[i].loaded = 0;
+                       }
                }
        }
 
+       iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
+                       0, &cp_probe);
+       if (iRet)
+               EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
+
+        iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
+                        0, &mr_probe);
+        if (iRet)
+                EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
+
+       iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
+                       0, &exit_probe);
+       if (iRet)
+               EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
+
+       iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
+                       0, &unmap_probe);
+       if (iRet)
+               EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
+
        return iRet;
 }
 static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
@@ -529,6 +532,46 @@ int inst_usr_space_proc (void)
 
        DPRINTF("User space instr");
 
+       // enable 'do_exit' probe to detect for remove task_struct
+       ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
+       if (ret != 0)
+       {
+               EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
+               return ret;
+       }
+
+       // enable 'mm_release' probe to detect when for remove user space probes
+       ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
+       if (ret != 0)
+       {
+               EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
+               return ret;
+       }
+
+       // enable 'do_munmap' probe to detect when for remove user space probes
+       ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
+       if (ret != 0)
+       {
+               EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
+               return ret;
+       }
+
+       /* enable 'copy_process' */
+       ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
+       if (ret != 0)
+       {
+               EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
+               return ret;
+       }
+
+       // enable 'do_page_fault' probe to detect when they will be loaded
+       ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
+       if (ret != 0)
+       {
+               EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
+               return ret;
+       }
+
 #ifdef SLP_APP
        launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
        if (launchpad_daemon_dentry == NULL) {
@@ -588,43 +631,6 @@ int inst_usr_space_proc (void)
                }
        }
 
-       // enable 'do_page_fault' probe to detect when they will be loaded
-       ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
-               return ret;
-       }
-       // enable 'do_exit' probe to detect for remove task_struct
-       ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
-               return ret;
-       }
-       /* enable 'copy_process' */
-       ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
-               return ret;
-       }
-
-       // enable 'mm_release' probe to detect when for remove user space probes
-       ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
-               return ret;
-       }
-
-       // enable 'do_munmap' probe to detect when for remove user space probes
-       ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
-               return ret;
-       }
        return 0;
 }
 
index e520c2b..be50667 100644 (file)
@@ -1281,14 +1281,16 @@ int kprobe_handler(struct pt_regs *regs)
                        p = get_kprobe_by_insn_slot(addr, tgid, regs);
                        if (!p) {
                                /* Not one of ours: let kernel handle it */
-                               DBPRINTF ("no_kprobe");
+                               printk("no_kprobe: Not one of ours: let "
+                                      "kernel handle it (userspace event) %p\n", addr);
                                goto no_kprobe;
                        }
                        retprobe = 1;
                        DBPRINTF ("uretprobe %p\n", addr);
                } else {
                        /* Not one of ours: let kernel handle it */
-                       DBPRINTF ("no_kprobe");
+                       printk("no_kprobe: Not one of ours: "
+                                 "let kernel handle it (kernel event)\n");
                        goto no_kprobe;
                }
        }
index 286de1f..b96a63f 100644 (file)
@@ -291,7 +291,7 @@ int dbi_disarm_urp_inst(struct kretprobe_instance *ri, struct task_struct *rm_ta
 
        retval = read_proc_vm_atomic(task, (unsigned long)stack, buf, sizeof(buf));
        if (retval != sizeof(buf)) {
-               printk("---> %s (%d/%d): failed to read stack from %08lx",
+               printk("---> %s (%d/%d): failed to read stack from %08lx\n",
                        task->comm, task->tgid, task->pid, (unsigned long)stack);
                retval = -EFAULT;
                goto out;
@@ -306,10 +306,10 @@ int dbi_disarm_urp_inst(struct kretprobe_instance *ri, struct task_struct *rm_ta
        }
 
        if (found) {
-               printk("---> %s (%d/%d): trampoline found at %08lx (%08lx /%+d) - %p\n",
-                               task->comm, task->tgid, task->pid,
-                               (unsigned long)found, (unsigned long)sp,
-                               found - sp, ri->rp->kp.addr);
+               /* printk("---> %s (%d/%d): trampoline found at %08lx (%08lx /%+d) - %p\n", */
+                               /* task->comm, task->tgid, task->pid, */
+                               /* (unsigned long)found, (unsigned long)sp, */
+                               /* found - sp, ri->rp->kp.addr); */
                retval = write_proc_vm_atomic(task, (unsigned long)found, &ri->ret_addr,
                                sizeof(ri->ret_addr));
                if (retval != sizeof(ri->ret_addr)) {
@@ -323,9 +323,9 @@ int dbi_disarm_urp_inst(struct kretprobe_instance *ri, struct task_struct *rm_ta
                struct pt_regs *uregs = task_pt_regs(ri->task);
                unsigned long ra = dbi_get_ret_addr(uregs);
                if (ra == (unsigned long)tramp) {
-                       printk("---> %s (%d/%d): trampoline found at lr = %08lx - %p\n",
-                                       task->comm, task->tgid, task->pid, ra, ri->rp->kp.addr);
-                       dbi_set_ret_addr(uregs, (unsigned long)tramp);
+                       /* printk("---> %s (%d/%d): trampoline found at lr = %08lx - %p\n", */
+                                       /* task->comm, task->tgid, task->pid, ra, ri->rp->kp.addr); */
+                       dbi_set_ret_addr(uregs, (unsigned long)ri->ret_addr);
                        retval = 0;
                } else {
                        printk("---> %s (%d/%d): trampoline NOT found at sp = %08lx, lr = %08lx - %p\n",
@@ -345,11 +345,12 @@ void dbi_unregister_uretprobe(struct task_struct *task, struct kretprobe *rp, in
        struct kretprobe_instance *ri;
        struct kretprobe *rp2 = NULL;
 
+       unregister_uprobe(&rp->kp, task, atomic);
        spin_lock_irqsave (&kretprobe_lock, flags);
 
        while ((ri = get_used_rp_inst(rp)) != NULL) {
                if (dbi_disarm_urp_inst(ri, NULL) != 0)
-                       /*panic*/printk("%s (%d/%d): cannot disarm urp instance (%08lx)\n",
+                       printk("%s (%d/%d): cannot disarm urp instance (%08lx)\n",
                                        ri->task->comm, ri->task->tgid, ri->task->pid,
                                        (unsigned long)rp->kp.addr);
                recycle_rp_inst(ri);
@@ -413,7 +414,6 @@ void dbi_unregister_uretprobe(struct task_struct *task, struct kretprobe *rp, in
        spin_unlock_irqrestore(&kretprobe_lock, flags);
        free_rp_inst(rp);
 
-       unregister_uprobe(&rp->kp, task, atomic);
 }
 
 void dbi_unregister_all_uprobes(struct task_struct *task, int atomic)
@@ -427,8 +427,8 @@ void dbi_unregister_all_uprobes(struct task_struct *task, int atomic)
                head = &kprobe_table[i];
                swap_hlist_for_each_entry_safe(p, node, tnode, head, hlist) {
                        if (p->tgid == task->tgid) {
-                               printk("dbi_unregister_all_uprobes: delete uprobe at %p[%lx] for %s/%d\n",
-                                               p->addr, (unsigned long)p->opcode, task->comm, task->pid);
+                               /* printk("dbi_unregister_all_uprobes: delete uprobe at %p[%lx] for %s/%d\n", */
+                               /*              p->addr, (unsigned long)p->opcode, task->comm, task->pid); */
                                unregister_uprobe(p, task, atomic);
                        }
                }