X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fptrace.c;h=7c76f2ffaeaad78060cfb3223857a89c7a4ccb8f;hb=18dabf473e15850c0dbc8ff13ac1e2806d542c15;hp=b1d11f1c7cf743a6d76f48fd1678d29314eb7b96;hpb=e245befce7af0a1e1347079ed62695b059594bd4;p=linux-2.6-omap-h63xx.git diff --git a/kernel/ptrace.c b/kernel/ptrace.c index b1d11f1c7cf..7c76f2ffaea 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -142,7 +143,7 @@ static int may_attach(struct task_struct *task) return -EPERM; smp_rmb(); if (task->mm) - dumpable = task->mm->dumpable; + dumpable = get_dumpable(task->mm); if (!dumpable && !capable(CAP_SYS_PTRACE)) return -EPERM; @@ -168,7 +169,7 @@ int ptrace_attach(struct task_struct *task) retval = -EPERM; if (task->pid <= 1) goto out; - if (task->tgid == current->tgid) + if (same_thread_group(task, current)) goto out; repeat: @@ -233,6 +234,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data) /* Architecture-specific hardware disable .. */ ptrace_disable(child); + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); write_lock_irq(&tasklist_lock); /* protect against de_thread()->release_task() */ @@ -385,6 +387,9 @@ int ptrace_request(struct task_struct *child, long request, case PTRACE_SETSIGINFO: ret = ptrace_setsiginfo(child, (siginfo_t __user *) data); break; + case PTRACE_DETACH: /* detach a process that was attached. */ + ret = ptrace_detach(child, data); + break; default: break; } @@ -439,7 +444,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid) return ERR_PTR(-EPERM); read_lock(&tasklist_lock); - child = find_task_by_pid(pid); + child = find_task_by_vpid(pid); if (child) get_task_struct(child); @@ -449,6 +454,10 @@ struct task_struct *ptrace_get_task_struct(pid_t pid) return child; } +#ifndef arch_ptrace_attach +#define arch_ptrace_attach(child) do { } while (0) +#endif + #ifndef __ARCH_SYS_PTRACE asmlinkage long sys_ptrace(long request, long pid, long addr, long data) { @@ -472,6 +481,12 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data) if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); + /* + * Some architectures need to do book-keeping after + * a ptrace attach. + */ + if (!ret) + arch_ptrace_attach(child); goto out_put_task_struct; } @@ -490,3 +505,22 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data) return ret; } #endif /* __ARCH_SYS_PTRACE */ + +int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) +{ + unsigned long tmp; + int copied; + + copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); + if (copied != sizeof(tmp)) + return -EIO; + return put_user(tmp, (unsigned long __user *)data); +} + +int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data) +{ + int copied; + + copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); + return (copied == sizeof(data)) ? 0 : -EIO; +}