[FIX] disarm uretprobe from child process 19/48919/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 1 Oct 2015 13:04:12 +0000 (16:04 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Thu, 1 Oct 2015 13:37:50 +0000 (06:37 -0700)
get_user can be used only if task->mm == current->mm
So for other case let call *_proc_vm_atomic()

Change-Id: I227da7e2ccfcb70fb3dd27b54f5ec4ad1056296e
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
uprobe/arch/x86/swap-asm/swap_uprobes.c

index 518c304..352d75c 100644 (file)
@@ -208,6 +208,24 @@ int arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs)
        return 0;
 }
 
+static bool get_long(struct task_struct *task,
+                    unsigned long vaddr, unsigned long *val)
+{
+       return task->mm == current->mm ?
+               !!get_user(*val, (unsigned long *)vaddr) :
+               sizeof(*val) != read_proc_vm_atomic(task, vaddr,
+                                                   val, sizeof(*val));
+}
+
+static bool put_long(struct task_struct *task,
+                    unsigned long vaddr, unsigned long *val)
+{
+       return task->mm == current->mm ?
+               !!put_user(*val, (unsigned long *)vaddr) :
+               sizeof(*val) != write_proc_vm_atomic(task, vaddr,
+                                                    val, sizeof(*val));
+}
+
 /**
  * @brief Disarms uretprobe on x86 arch.
  *
@@ -228,14 +246,14 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri,
        else
                tramp_addr = tr; /* ri - invalid */
 
-       if (get_user(ret_addr, (unsigned long *)sp)) {
+       if (get_long(task, sp, &ret_addr)) {
                printk(KERN_INFO "---> %s (%d/%d): failed to read stack from %08lx\n",
                       task->comm, task->tgid, task->pid, sp);
                return -EFAULT;
        }
 
        if (tramp_addr == ret_addr) {
-               if (put_user((unsigned long)ri->ret_addr, (unsigned long *)sp)) {
+               if (put_long(task, sp, (unsigned long *)&ri->ret_addr)) {
                        printk(KERN_INFO "---> %s (%d/%d): failed to write "
                               "orig_ret_addr to %08lx",
                               task->comm, task->tgid, task->pid, sp);