As part of my previous sys_ptrace consolidation I introduce a
ptrace_get_task_struct helper, that gets a reference to the taskstruct
for a given pid, after doing all the ptrace attach checks.
This pathces makes all but a few ptrace and compat_ptrace
implementations use it. The implementations not covered are:
- m68k: has some large ptrace changes pending, should be converted to
the common sys_ptrace later
- ia64 (native ptrace only): does some wierd stuff about finding a
different thread in the same threadgroup
Signed-off-by: Christoph Hellwig <[email protected]>
Index: linux-2.6/arch/alpha/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/ptrace.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/alpha/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -265,28 +265,7 @@
lock_kernel();
DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
request, pid, addr, data));
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out_notsk;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out_notsk;
- /* set the ptrace bit in the process ptrace flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out_notsk;
- }
- if (pid == 1) /* you may not mess with init */
- goto out_notsk;
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out_notsk;
Index: linux-2.6/arch/ia64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.orig/arch/ia64/ia32/sys_ia32.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/ia64/ia32/sys_ia32.c 2005-08-13 18:14:22.000000000 +0200
@@ -1759,22 +1759,9 @@
long i, ret;
lock_kernel();
- if (request == PTRACE_TRACEME) {
- ret = sys_ptrace(request, pid, addr, data);
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
if (request == PTRACE_ATTACH) {
ret = sys_ptrace(request, pid, addr, data);
Index: linux-2.6/arch/m32r/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/ptrace.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/m32r/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -762,29 +762,10 @@
int ret;
lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out;
-
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
if (ret == 0)
Index: linux-2.6/arch/mips/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace32.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/mips/kernel/ptrace32.c 2005-08-13 18:14:22.000000000 +0200
@@ -50,31 +50,10 @@
(unsigned long) data);
#endif
lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- if ((ret = security_ptrace(current->parent, current)))
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
goto out_tsk;
Index: linux-2.6/arch/parisc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/parisc/kernel/ptrace.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/parisc/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -87,33 +87,9 @@
#endif
lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
-
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
Index: linux-2.6/arch/ppc64/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/ppc64/kernel/ptrace32.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/ppc64/kernel/ptrace32.c 2005-08-13 18:14:22.000000000 +0200
@@ -45,31 +45,10 @@
int ret = -EPERM;
lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
goto out_tsk;
Index: linux-2.6/arch/s390/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/ptrace.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/s390/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -712,36 +712,11 @@
int ret;
lock_kernel();
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- ret = -EPERM;
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- goto out;
+ ret = ptrace_get_task_struct(request, pid, &child);
+ if (child) {
+ ret = do_ptrace(child, request, addr, data);
+ put_task_struct(child);
}
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out;
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = do_ptrace(child, request, addr, data);
-
- put_task_struct(child);
out:
unlock_kernel();
return ret;
Index: linux-2.6/arch/sparc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/ptrace.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/sparc/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -286,40 +286,13 @@
s, (int) request, (int) pid, addr, data, addr2);
}
#endif
- if (request == PTRACE_TRACEME) {
- int my_ret;
-
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- pt_error_return(regs, EPERM);
- goto out;
- }
- my_ret = security_ptrace(current->parent, current);
- if (my_ret) {
- pt_error_return(regs, -my_ret);
- goto out;
- }
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- pt_succ_return(regs, 0);
- goto out;
- }
-#ifndef ALLOW_INIT_TRACING
- if (pid == 1) {
- /* Can't dork with init. */
- pt_error_return(regs, EPERM);
- goto out;
- }
-#endif
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child) {
- pt_error_return(regs, ESRCH);
+ if (ret)
+ pt_error_return(regs, -ret);
+ else
+ pt_succ_return(regs, 0);
goto out;
}
Index: linux-2.6/arch/sparc64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc64/kernel/ptrace.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/sparc64/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -188,40 +188,12 @@
s, request, pid, addr, data, addr2);
}
#endif
- if (request == PTRACE_TRACEME) {
- int ret;
-
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- pt_error_return(regs, EPERM);
- goto out;
- }
- ret = security_ptrace(current->parent, current);
- if (ret) {
- pt_error_return(regs, -ret);
- goto out;
- }
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- pt_succ_return(regs, 0);
- goto out;
- }
-#ifndef ALLOW_INIT_TRACING
- if (pid == 1) {
- /* Can't dork with init. */
- pt_error_return(regs, EPERM);
- goto out;
- }
-#endif
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
-
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child) {
- pt_error_return(regs, ESRCH);
+ if (ret)
+ pt_error_return(regs, -ret);
+ else
+ pt_succ_return(regs, 0);
goto out;
}
Index: linux-2.6/arch/x86_64/ia32/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/x86_64/ia32/ptrace32.c 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/x86_64/ia32/ptrace32.c 2005-08-13 18:14:22.000000000 +0200
@@ -196,36 +196,6 @@
#undef R32
-static struct task_struct *find_target(int request, int pid, int *err)
-{
- struct task_struct *child;
-
- *err = -EPERM;
- if (pid == 1)
- return NULL;
-
- *err = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (child) {
- *err = -EPERM;
- if (child->pid == 1)
- goto out;
- *err = ptrace_check_attach(child, request == PTRACE_KILL);
- if (*err < 0)
- goto out;
- return child;
- }
- out:
- if (child)
- put_task_struct(child);
- return NULL;
-
-}
-
asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
{
struct task_struct *child;
@@ -254,10 +224,14 @@
break;
}
- child = find_target(request, pid, &ret);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
return ret;
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out;
+
childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs));
switch (request) {
@@ -373,6 +347,7 @@
break;
}
+ out:
put_task_struct(child);
return ret;
}
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-08-13 18:14:17.000000000 +0200
+++ linux-2.6/kernel/ptrace.c 2005-08-13 18:14:22.000000000 +0200
@@ -389,9 +389,7 @@
return ret;
}
-#ifndef __ARCH_SYS_PTRACE
-static int ptrace_get_task_struct(long request, long pid,
- struct task_struct **childp)
+int ptrace_get_task_struct(long request, long pid, struct task_struct **childp)
{
struct task_struct *child;
int ret;
@@ -437,6 +435,7 @@
return 0;
}
+#ifndef __ARCH_SYS_PTRACE
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h 2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/include/linux/ptrace.h 2005-08-13 18:14:22.000000000 +0200
@@ -78,6 +78,7 @@
extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
+extern int ptrace_get_task_struct(long request, long pid, struct task_struct **childp);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
extern int ptrace_attach(struct task_struct *tsk);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
|
|