* [PATCH] consolidate sys_ptrace
@ 2005-08-10 8:00 Christoph Hellwig
2005-08-10 8:33 ` Martin Schwidefsky
` (9 more replies)
0 siblings, 10 replies; 27+ messages in thread
From: Christoph Hellwig @ 2005-08-10 8:00 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-arch
The sys_ptrace boilerplate code (everything outside the big switch
statement for the arch-specific requests) is shared by most
architectures. This patch moves it to kernel/ptrace.c and leaves the
arch-specific code as arch_ptrace.
Some architectures have a too different ptrace so we have to exclude
them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
keep their implementations. For sh64 I had to add a sh64_ptrace wrapper
because it does some initialization on the first call. For um I removed
an ifdefed SUBARCH_PTRACE_SPECIAL block, but SUBARCH_PTRACE_SPECIAL
isn't defined anywhere in the tree.
Only tested on ppc32 so far.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/arch/arm/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/arm/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -648,7 +648,7 @@
#endif
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -782,53 +782,6 @@
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
Index: linux-2.6/arch/arm26/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/arm26/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/arm26/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -546,7 +546,7 @@
sizeof(struct user_fp)) ? -EFAULT : 0;
}
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -665,53 +665,6 @@
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
Index: linux-2.6/arch/frv/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/frv/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/frv/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -106,48 +106,11 @@
child->thread.frame0->__status |= REG__STATUS_STEP;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
int ret;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/h8300/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/h8300/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/h8300/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -57,43 +57,10 @@
h8300_disable_trace(child);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/i386/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/i386/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/i386/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -352,49 +352,12 @@
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int i, ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -649,10 +612,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/m68k/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m68k/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/m68k/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -117,44 +117,10 @@
child->thread.work.syscall_trace = 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -368,10 +334,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/m68knommu/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m68knommu/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/m68knommu/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -101,43 +101,10 @@
put_reg(child, PT_SR, tmp);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(truct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -357,10 +324,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/mips/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/mips/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -47,51 +47,10 @@
/* Nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
-#if 0
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -294,10 +253,6 @@
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/ppc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/ppc/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/ppc/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -240,46 +240,10 @@
clear_single_step(child);
}
-int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -451,10 +415,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/ppc64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/ppc64/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/ppc64/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -52,46 +52,10 @@
clear_single_step(child);
}
-int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -278,10 +242,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/s390/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/s390/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -613,8 +613,7 @@
#define PT32_IEEE_IP 0x13c
-static int
-do_ptrace(struct task_struct *child, long request, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
int ret;
@@ -705,48 +704,6 @@
return -EIO;
}
-asmlinkage long
-sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- 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 = -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;
-}
-
asmlinkage void
syscall_trace(struct pt_regs *regs, int entryexit)
{
Index: linux-2.6/arch/sh/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/sh/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -80,48 +80,11 @@
/* nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int ret;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -289,10 +252,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/v850/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/v850/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/v850/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -113,45 +113,10 @@
return 1;
}
-int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int rval;
- lock_kernel();
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- rval = -EPERM;
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- rval = 0;
- goto out;
- }
- rval = -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;
-
- rval = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- rval = ptrace_attach(child);
- goto out_tsk;
- }
- rval = ptrace_check_attach(child, request == PTRACE_KILL);
- if (rval < 0)
- goto out_tsk;
-
switch (request) {
unsigned long val, copied;
@@ -249,10 +214,6 @@
goto out;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return rval;
}
Index: linux-2.6/arch/x86_64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/x86_64/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/x86_64/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -313,48 +313,11 @@
}
-asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, unsigned long addr, long data)
{
- struct task_struct *child;
long i, ret;
unsigned ui;
- /* This lock_kernel fixes a subtle race with suid exec */
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -608,10 +571,6 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/xtensa/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/xtensa/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/xtensa/kernel/ptrace.c 2005-08-09 23:29:50.000000000 +0200
@@ -45,58 +45,10 @@
/* Nothing to do.. */
}
-int sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret = -EPERM;
- lock_kernel();
-
-#if 0
- if ((int)request != 1)
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (unsigned long) data);
-#endif
-
- 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);
- 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);
- goto out_tsk;
- }
-
- if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@
ret = ptrace_request(child, request, addr, data);
goto out;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-08-09 20:16:57.000000000 +0200
+++ linux-2.6/kernel/ptrace.c 2005-08-10 00:03:17.000000000 +0200
@@ -388,3 +388,72 @@
return ret;
}
+
+#ifndef __ARCH_SYS_PTRACE
+static int ptrace_get_task_struct(long request, long pid,
+ struct task_struct **childp)
+{
+ struct task_struct *child;
+ int ret;
+
+ if (request == PTRACE_TRACEME) {
+ /* are we already being traced? */
+ if (current->ptrace & PT_PTRACED)
+ return -EPERM;
+ ret = security_ptrace(current->parent, current);
+ if (ret)
+ return -EPERM;
+ /* set the ptrace bit in the process ptrace flags. */
+ current->ptrace |= PT_PTRACED;
+ return 0;
+ }
+
+ /* you may not mess with init */
+ if (pid == 1)
+ return -EPERM;
+
+ ret = -ESRCH;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ return -ESRCH;
+
+ *childp = child;
+ return 0;
+}
+
+/* Not used by alpha, m32r, ia64, parisc, sh64, sparc, sparc64 */
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+{
+ struct task_struct *child = NULL;
+ int ret;
+
+ /* This lock_kernel fixes a subtle race with suid exec */
+ lock_kernel();
+ ret = ptrace_get_task_struct(request, pid, &child);
+ if (!child)
+ goto out;
+
+ if (request == PTRACE_ATTACH) {
+ ret = ptrace_attach(child);
+ goto out;
+ }
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ ret = arch_ptrace(child, request, addr, data);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ out_put_task_struct:
+ put_task_struct(child);
+ out:
+ unlock_kernel();
+ return ret;
+}
+#endif /* __ARCH_SYS_PTRACE */
Index: linux-2.6/arch/cris/arch-v10/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v10/kernel/ptrace.c 2005-07-28 19:32:16.000000000 +0200
+++ linux-2.6/arch/cris/arch-v10/kernel/ptrace.c 2005-08-09 23:34:26.000000000 +0200
@@ -76,55 +76,11 @@
* (in user space) where the result of the ptrace call is written (instead of
* being returned).
*/
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/cris/arch-v32/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v32/kernel/ptrace.c 2005-07-28 19:32:17.000000000 +0200
+++ linux-2.6/arch/cris/arch-v32/kernel/ptrace.c 2005-08-09 23:35:12.000000000 +0200
@@ -99,55 +99,11 @@
}
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/um/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/um/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/um/kernel/ptrace.c 2005-08-09 23:38:02.000000000 +0200
@@ -43,53 +43,10 @@
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
-long sys_ptrace(long request, long pid, long addr, long data)
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int i, ret;
- 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);
- 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;
- }
-
-#ifdef SUBACH_PTRACE_SPECIAL
- SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -282,10 +239,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
- out_tsk:
- put_task_struct(child);
- out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/include/asm-alpha/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-alpha/ptrace.h 2005-04-30 10:17:18.000000000 +0200
+++ linux-2.6/include/asm-alpha/ptrace.h 2005-08-09 23:56:12.000000000 +0200
@@ -67,6 +67,9 @@
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
Index: linux-2.6/include/asm-arm/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-arm/unistd.h 2005-04-30 10:17:18.000000000 +0200
+++ linux-2.6/include/asm-arm/unistd.h 2005-08-09 23:51:25.000000000 +0200
@@ -537,7 +537,6 @@
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-arm26/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-arm26/unistd.h 2005-04-30 10:17:18.000000000 +0200
+++ linux-2.6/include/asm-arm26/unistd.h 2005-08-09 23:51:23.000000000 +0200
@@ -480,7 +480,6 @@
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-cris/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-cris/unistd.h 2005-07-28 19:32:32.000000000 +0200
+++ linux-2.6/include/asm-cris/unistd.h 2005-08-09 23:51:28.000000000 +0200
@@ -367,7 +367,6 @@
asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
long mof, long srp, struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-h8300/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-h8300/unistd.h 2005-04-30 10:17:18.000000000 +0200
+++ linux-2.6/include/asm-h8300/unistd.h 2005-08-09 23:51:31.000000000 +0200
@@ -528,7 +528,6 @@
asmlinkage int sys_execve(char *name, char **argv, char **envp,
int dummy, ...);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-i386/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-i386/unistd.h 2005-07-24 23:25:03.000000000 +0200
+++ linux-2.6/include/asm-i386/unistd.h 2005-08-09 23:51:33.000000000 +0200
@@ -448,7 +448,6 @@
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_vfork(struct pt_regs regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage long sys_iopl(unsigned long unused);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
Index: linux-2.6/include/asm-ia64/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-ia64/ptrace.h 2005-04-30 10:17:18.000000000 +0200
+++ linux-2.6/include/asm-ia64/ptrace.h 2005-08-09 23:55:57.000000000 +0200
@@ -227,6 +227,9 @@
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
/*
* We use the ia64_psr(regs)->ri to determine which of the three
* instructions in bundle (16 bytes) took the sample. Generate
Index: linux-2.6/include/asm-m32r/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-m32r/ptrace.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-m32r/ptrace.h 2005-08-09 23:55:51.000000000 +0200
@@ -145,6 +145,9 @@
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
#elif defined(CONFIG_ISA_M32R)
Index: linux-2.6/include/asm-m68k/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-m68k/unistd.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-m68k/unistd.h 2005-08-09 23:52:53.000000000 +0200
@@ -444,7 +444,6 @@
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
Index: linux-2.6/include/asm-m68knommu/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-m68knommu/unistd.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-m68knommu/unistd.h 2005-08-09 23:51:40.000000000 +0200
@@ -504,7 +504,6 @@
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
int sys_request_irq(unsigned int,
irqreturn_t (*)(int, void *, struct pt_regs *),
Index: linux-2.6/include/asm-mips/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-mips/unistd.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-mips/unistd.h 2005-08-09 23:52:56.000000000 +0200
@@ -1164,7 +1164,6 @@
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-parisc/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-parisc/ptrace.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-parisc/ptrace.h 2005-08-09 23:56:00.000000000 +0200
@@ -45,6 +45,9 @@
#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */
#ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE 1
+
+
/* XXX should we use iaoq[1] or iaoq[0] ? */
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
Index: linux-2.6/include/asm-ppc/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-ppc/unistd.h 2005-08-06 14:56:38.000000000 +0200
+++ linux-2.6/include/asm-ppc/unistd.h 2005-08-09 23:53:05.000000000 +0200
@@ -469,7 +469,6 @@
int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
struct pt_regs *regs);
int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-ppc64/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-ppc64/unistd.h 2005-08-02 11:57:28.000000000 +0200
+++ linux-2.6/include/asm-ppc64/unistd.h 2005-08-09 23:53:03.000000000 +0200
@@ -467,7 +467,6 @@
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs);
int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
long sys_rt_sigaction(int sig, const struct sigaction __user *act,
struct sigaction __user *oact, size_t sigsetsize);
Index: linux-2.6/include/asm-s390/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-s390/unistd.h 2005-08-06 14:57:26.000000000 +0200
+++ linux-2.6/include/asm-s390/unistd.h 2005-08-09 23:53:10.000000000 +0200
@@ -590,7 +590,6 @@
asmlinkage long sys_fork(struct pt_regs regs);
asmlinkage long sys_vfork(struct pt_regs regs);
asmlinkage long sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-sh/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-sh/unistd.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-sh/unistd.h 2005-08-09 23:53:16.000000000 +0200
@@ -497,7 +497,6 @@
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
size_t count, long dummy, loff_t pos);
asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
Index: linux-2.6/include/asm-sparc/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-sparc/ptrace.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-sparc/ptrace.h 2005-08-09 23:56:07.000000000 +0200
@@ -60,6 +60,9 @@
#define STACKFRAME_SZ sizeof(struct sparc_stackf)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
unsigned long profile_pc(struct pt_regs *);
Index: linux-2.6/include/asm-sparc64/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-sparc64/ptrace.h 2005-07-28 19:32:32.000000000 +0200
+++ linux-2.6/include/asm-sparc64/ptrace.h 2005-08-09 23:56:10.000000000 +0200
@@ -94,6 +94,9 @@
#define STACKFRAME32_SZ sizeof(struct sparc_stackf32)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
Index: linux-2.6/include/asm-v850/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-v850/unistd.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/asm-v850/unistd.h 2005-08-09 23:53:26.000000000 +0200
@@ -452,7 +452,6 @@
struct pt_regs;
int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
int sys_pipe (int *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-x86_64/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-x86_64/unistd.h 2005-07-28 19:32:32.000000000 +0200
+++ linux-2.6/include/asm-x86_64/unistd.h 2005-08-09 23:53:35.000000000 +0200
@@ -780,8 +780,6 @@
#include <linux/types.h>
#include <asm/ptrace.h>
-asmlinkage long sys_ptrace(long request, long pid,
- unsigned long addr, long data);
asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
struct sigaction;
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h 2005-04-30 10:17:19.000000000 +0200
+++ linux-2.6/include/linux/ptrace.h 2005-08-10 00:03:05.000000000 +0200
@@ -76,6 +76,8 @@
#include <linux/compiler.h> /* For unlikely. */
#include <linux/sched.h> /* For struct task_struct. */
+
+extern int arch_ptrace(struct task_struct *child, long request, long addr, long data);
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);
Index: linux-2.6/arch/sh64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sh64/kernel/ptrace.c 2005-08-09 20:16:55.000000000 +0200
+++ linux-2.6/arch/sh64/kernel/ptrace.c 2005-08-10 00:00:19.000000000 +0200
@@ -121,61 +121,11 @@
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+
+int arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
- extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
-#define WPC_DBRMODE 0x0d104008
- static int first_call = 1;
int ret;
- lock_kernel();
-
- if (first_call) {
- /* Set WPC.DBRMODE to 0. This makes all debug events get
- * delivered through RESVEC, i.e. into the handlers in entry.S.
- * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
- * would normally be left set to 1, which makes debug events get
- * delivered through DBRVEC, i.e. into the remote gdb's
- * handlers. This prevents ptrace getting them, and confuses
- * the remote gdb.) */
- printk("DBRMODE set to 0 to permit native debugging\n");
- poke_real_address_q(WPC_DBRMODE, 0);
- first_call = 0;
- }
-
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +263,33 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
+asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+{
+ extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+#define WPC_DBRMODE 0x0d104008
+ static int first_call = 1;
+
+ lock_kernel();
+ if (first_call) {
+ /* Set WPC.DBRMODE to 0. This makes all debug events get
+ * delivered through RESVEC, i.e. into the handlers in entry.S.
+ * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
+ * would normally be left set to 1, which makes debug events get
+ * delivered through DBRVEC, i.e. into the remote gdb's
+ * handlers. This prevents ptrace getting them, and confuses
+ * the remote gdb.) */
+ printk("DBRMODE set to 0 to permit native debugging\n");
+ poke_real_address_q(WPC_DBRMODE, 0);
+ first_call = 0;
+ }
+ unlock_kernel();
+
+ return sys_ptrace(request, pid, addr, data);
+}
+
asmlinkage void syscall_trace(void)
{
struct task_struct *tsk = current;
Index: linux-2.6/arch/sh64/kernel/syscalls.S
===================================================================
--- linux-2.6.orig/arch/sh64/kernel/syscalls.S 2005-05-03 09:12:32.000000000 +0200
+++ linux-2.6/arch/sh64/kernel/syscalls.S 2005-08-09 23:58:21.000000000 +0200
@@ -46,7 +46,7 @@
.long sys_setuid16
.long sys_getuid16
.long sys_stime /* 25 */
- .long sys_ptrace
+ .long sh64_ptrace
.long sys_alarm
.long sys_fstat
.long sys_pause
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
@ 2005-08-10 8:33 ` Martin Schwidefsky
2005-08-10 8:38 ` Christoph Hellwig
2005-08-10 8:43 ` Andi Kleen
` (8 subsequent siblings)
9 siblings, 1 reply; 27+ messages in thread
From: Martin Schwidefsky @ 2005-08-10 8:33 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-arch, linux-kernel
Christoph Hellwig <hch@lst.de> wrote on 08/10/2005 10:00:57 AM:
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
>
> Some architectures have a too different ptrace so we have to exclude
> them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
> keep their implementations. For sh64 I had to add a sh64_ptrace wrapper
> because it does some initialization on the first call. For um I removed
> an ifdefed SUBARCH_PTRACE_SPECIAL block, but SUBARCH_PTRACE_SPECIAL
> isn't defined anywhere in the tree.
There is one small problem with the new ptrace code for s390. We have
this horribly broken ptrace hack to get the ieee instruction pointer
of the last fpu exception. The fpu itself doesn't store the value so
the exception handler of the kernel stores the instruction pointer to
the thread structure. A process is allowed to ptrace itself (!) with the
peek/poke value of PT_IEEE_IP to get this value. This is used in the
fpu code in glibc. I know this is broken but I can't help it. Without
this hack existing glibc code will fall over.
To make this work the special case needs to be dealt with before the
ptrace_check_attach check is done. My suggestion would be to move the
ptrace_check_attach to the arch_ptrace function. Then the s390 specific
arch_ptrace function could insert the PT_IEEE_IP check before calling
ptrace_chek_attach. The only other alternative is a s390 copy of
sys_ptrace.
blue skies,
Martin
Martin Schwidefsky
Linux for zSeries Development & Services
IBM Deutschland Entwicklung GmbH
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:33 ` Martin Schwidefsky
@ 2005-08-10 8:38 ` Christoph Hellwig
0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2005-08-10 8:38 UTC (permalink / raw)
To: Martin Schwidefsky; +Cc: akpm, linux-arch, linux-kernel
On Wed, Aug 10, 2005 at 10:33:50AM +0200, Martin Schwidefsky wrote:
> Christoph Hellwig <hch@lst.de> wrote on 08/10/2005 10:00:57 AM:
>
> > The sys_ptrace boilerplate code (everything outside the big switch
> > statement for the arch-specific requests) is shared by most
> > architectures. This patch moves it to kernel/ptrace.c and leaves the
> > arch-specific code as arch_ptrace.
> >
> > Some architectures have a too different ptrace so we have to exclude
> > them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
> > keep their implementations. For sh64 I had to add a sh64_ptrace wrapper
> > because it does some initialization on the first call. For um I removed
> > an ifdefed SUBARCH_PTRACE_SPECIAL block, but SUBARCH_PTRACE_SPECIAL
> > isn't defined anywhere in the tree.
>
> There is one small problem with the new ptrace code for s390. We have
> this horribly broken ptrace hack to get the ieee instruction pointer
> of the last fpu exception. The fpu itself doesn't store the value so
> the exception handler of the kernel stores the instruction pointer to
> the thread structure. A process is allowed to ptrace itself (!) with the
> peek/poke value of PT_IEEE_IP to get this value. This is used in the
> fpu code in glibc. I know this is broken but I can't help it. Without
> this hack existing glibc code will fall over.
>
> To make this work the special case needs to be dealt with before the
> ptrace_check_attach check is done. My suggestion would be to move the
> ptrace_check_attach to the arch_ptrace function. Then the s390 specific
> arch_ptrace function could insert the PT_IEEE_IP check before calling
> ptrace_chek_attach. The only other alternative is a s390 copy of
> sys_ptrace.
I suspect at this point it's better to leave s390 out of the
consolidation. I'll have another patch that'll make the implementations
that aren't consolidated use the new ptrace_get_task_struct function,
so there will be far less code duplicated than now.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
2005-08-10 8:33 ` Martin Schwidefsky
@ 2005-08-10 8:43 ` Andi Kleen
2005-08-10 9:36 ` David Howells
` (7 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Andi Kleen @ 2005-08-10 8:43 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
x86-64 part is ok for me.
-Andi
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
2005-08-10 8:33 ` Martin Schwidefsky
2005-08-10 8:43 ` Andi Kleen
@ 2005-08-10 9:36 ` David Howells
2005-08-10 12:46 ` Paul Mundt
` (6 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: David Howells @ 2005-08-10 9:36 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
Christoph Hellwig <hch@lst.de> wrote:
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
Looks okay for FRV.
My biggest concern with doing things like this is that it eats away at the
kernel stack space available for a syscall, though I don't think it'll be too
much of a problem in this case.
Is there also a way to get rid of the lock_kernel() call?
David
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (2 preceding siblings ...)
2005-08-10 9:36 ` David Howells
@ 2005-08-10 12:46 ` Paul Mundt
2005-08-10 13:15 ` Ralf Baechle
` (5 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Paul Mundt @ 2005-08-10 12:46 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
[-- Attachment #1: Type: text/plain, Size: 492 bytes --]
On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> Some architectures have a too different ptrace so we have to exclude
> them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
> keep their implementations. For sh64 I had to add a sh64_ptrace wrapper
> because it does some initialization on the first call. For um I removed
> an ifdefed SUBARCH_PTRACE_SPECIAL block, but SUBARCH_PTRACE_SPECIAL
> isn't defined anywhere in the tree.
Looks ok for sh and sh64.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (3 preceding siblings ...)
2005-08-10 12:46 ` Paul Mundt
@ 2005-08-10 13:15 ` Ralf Baechle
2005-08-10 13:28 ` Jeff Dike
` (4 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Ralf Baechle @ 2005-08-10 13:15 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
>
> Some architectures have a too different ptrace so we have to exclude
> them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
> keep their implementations. For sh64 I had to add a sh64_ptrace wrapper
> because it does some initialization on the first call. For um I removed
> an ifdefed SUBARCH_PTRACE_SPECIAL block, but SUBARCH_PTRACE_SPECIAL
> isn't defined anywhere in the tree.
>
> Only tested on ppc32 so far.
MIPS bits looking good.
Ralf
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (4 preceding siblings ...)
2005-08-10 13:15 ` Ralf Baechle
@ 2005-08-10 13:28 ` Jeff Dike
2005-08-10 17:08 ` Richard Henderson
` (3 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Jeff Dike @ 2005-08-10 13:28 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
OK for UML.
Jeff
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (5 preceding siblings ...)
2005-08-10 13:28 ` Jeff Dike
@ 2005-08-10 17:08 ` Richard Henderson
2005-08-11 10:44 ` Roman Zippel
` (2 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2005-08-10 17:08 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> Some architectures have a too different ptrace so we have to exclude
> them: alpha...
Alpha could be updated to use this, I think. Just a matter of
using force_successful_syscall_return instead of pt_regs directly.
I'll have a look at testing this.
r~
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (6 preceding siblings ...)
2005-08-10 17:08 ` Richard Henderson
@ 2005-08-11 10:44 ` Roman Zippel
2005-08-11 13:51 ` Christoph Hellwig
2005-08-11 16:51 ` Russell King
2005-08-11 17:32 ` Richard Henderson
9 siblings, 1 reply; 27+ messages in thread
From: Roman Zippel @ 2005-08-11 10:44 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Andrew Morton, linux-kernel, linux-arch, Alexander Viro
Hi,
On Wed, 10 Aug 2005, Christoph Hellwig wrote:
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
No objection really, but I recently reformatted the m68k sys_ptrace() so
it would be easier to regenerate your changes on top of this. I can do
this for you if we can agree on to merge at least the m68k ptrace changes
before this.
For reference I put the patches at www.xs4all.nl/~zippel/m68k_merge/
(tf, p_ws, p_c are the relevant patches).
Al, this also includes the updated thread_info patches, I fixed some of
m68k specific parts. Could you please expand a little on the objections
you made on IRC?
bye, Roman
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-11 10:44 ` Roman Zippel
@ 2005-08-11 13:51 ` Christoph Hellwig
0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2005-08-11 13:51 UTC (permalink / raw)
To: Roman Zippel; +Cc: Andrew Morton, linux-kernel, linux-arch, Alexander Viro
On Thu, Aug 11, 2005 at 12:44:34PM +0200, Roman Zippel wrote:
> No objection really, but I recently reformatted the m68k sys_ptrace() so
> it would be easier to regenerate your changes on top of this. I can do
> this for you if we can agree on to merge at least the m68k ptrace changes
> before this.
> For reference I put the patches at www.xs4all.nl/~zippel/m68k_merge/
> (tf, p_ws, p_c are the relevant patches).
I'll leave m68k out of the patchset for now. If you have your patches
done when I'm doing the next round of changes in I'll do it atop of
those, else you'll have to redo your changes, bad luck for not syncing
up with mainline.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (7 preceding siblings ...)
2005-08-11 10:44 ` Roman Zippel
@ 2005-08-11 16:51 ` Russell King
2005-08-11 17:32 ` Richard Henderson
9 siblings, 0 replies; 27+ messages in thread
From: Russell King @ 2005-08-11 16:51 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Thanks Christoph.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
` (8 preceding siblings ...)
2005-08-11 16:51 ` Russell King
@ 2005-08-11 17:32 ` Richard Henderson
2005-08-11 17:33 ` Christoph Hellwig
9 siblings, 1 reply; 27+ messages in thread
From: Richard Henderson @ 2005-08-11 17:32 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
The signature of arch_ptrace needs to return long, and not int.
The PTRACE_PEEK{TEXT,DATA,USR} requests return a "word", which
on 64-bit arches needs to be a 64-bit type.
r~
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH] consolidate sys_ptrace
2005-08-11 17:32 ` Richard Henderson
@ 2005-08-11 17:33 ` Christoph Hellwig
0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2005-08-11 17:33 UTC (permalink / raw)
To: Christoph Hellwig, akpm, linux-kernel, linux-arch
On Thu, Aug 11, 2005 at 10:32:03AM -0700, Richard Henderson wrote:
> On Wed, Aug 10, 2005 at 10:00:57AM +0200, Christoph Hellwig wrote:
> > The sys_ptrace boilerplate code (everything outside the big switch
> > statement for the arch-specific requests) is shared by most
> > architectures. This patch moves it to kernel/ptrace.c and leaves the
> > arch-specific code as arch_ptrace.
>
> The signature of arch_ptrace needs to return long, and not int.
> The PTRACE_PEEK{TEXT,DATA,USR} requests return a "word", which
> on 64-bit arches needs to be a 64-bit type.
Ok. Will be that way in the next patch.
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH] consolidate sys_ptrace
@ 2005-08-10 16:59 Luck, Tony
2005-08-11 0:20 ` Stephen Rothwell
0 siblings, 1 reply; 27+ messages in thread
From: Luck, Tony @ 2005-08-10 16:59 UTC (permalink / raw)
To: Christoph Hellwig, akpm; +Cc: linux-kernel, linux-arch
>Some architectures have a too different ptrace so we have to exclude
>them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
>keep their implementations.
So it should be no surprise that this patch works ok for ia64, but here
is the ACK anyway.
>+#ifndef __ARCH_SYS_PTRACE
Most of the existing "#define ARCH_foo" uses don't have a prepended
"__" (current score is 20 to 3). So there is a small question of
going with the prevailing style, or doing the right thing. Just in
case anyone else raises this, my vote is with "__".
-Tony
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH] consolidate sys_ptrace
2005-08-10 16:59 Luck, Tony
@ 2005-08-11 0:20 ` Stephen Rothwell
0 siblings, 0 replies; 27+ messages in thread
From: Stephen Rothwell @ 2005-08-11 0:20 UTC (permalink / raw)
To: Luck, Tony; +Cc: hch, akpm, linux-kernel, linux-arch
On Wed, 10 Aug 2005 09:59:01 -0700 "Luck, Tony" <tony.luck@intel.com>
wrote:
>
> >Some architectures have a too different ptrace so we have to exclude
> >them: alpha, ia64, m32r, parisc, sparc, sparc64. They continue to
> >keep their implementations.
>
> So it should be no surprise that this patch works ok for ia64, but here
> is the ACK anyway.
>
> >+#ifndef __ARCH_SYS_PTRACE
>
> Most of the existing "#define ARCH_foo" uses don't have a prepended
> "__" (current score is 20 to 3). So there is a small question of
As opposed to the 86 unique HAVE_ARCH_ defines ...
(like: HAVE_ARCH_COPY_AND_CSUM_FROM_USER, HAVE_ARCH_COPY_SIGINFO etc)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH consolidate sys_ptrace
@ 2005-11-01 5:09 Christoph Hellwig
2005-11-01 5:12 ` Christoph Hellwig
0 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2005-11-01 5:09 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-arch
[Let's try again now that sys_ptrace returns long everywhere mainline..]
The sys_ptrace boilerplate code (everything outside the big switch
statement for the arch-specific requests) is shared by most
architectures. This patch moves it to kernel/ptrace.c and leaves the
arch-specific code as arch_ptrace.
Some architectures have a too different ptrace so we have to exclude
them. They continue to keep their implementations. For sh64 I had to
add a sh64_ptrace wrapper because it does some initialization on the
first call. For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block,
but SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/arch/arm/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/arm/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -648,7 +648,7 @@
#endif
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -782,53 +782,6 @@
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
Index: linux-2.6/arch/arm26/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/arm26/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/arm26/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -546,7 +546,7 @@
sizeof(struct user_fp)) ? -EFAULT : 0;
}
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -665,53 +665,6 @@
return ret;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
Index: linux-2.6/arch/frv/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/frv/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/frv/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -106,48 +106,11 @@
child->thread.frame0->__status |= REG__STATUS_STEP;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
int ret;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/h8300/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/h8300/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/h8300/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -57,43 +57,10 @@
h8300_disable_trace(child);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/i386/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/i386/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/i386/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -352,49 +352,12 @@
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int i, ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -649,10 +612,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/m68knommu/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m68knommu/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/m68knommu/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -101,43 +101,10 @@
put_reg(child, PT_SR, tmp);
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(truct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -357,10 +324,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/mips/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/mips/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -47,51 +47,10 @@
/* Nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
-#if 0
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -294,10 +253,6 @@
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/ppc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/ppc/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/ppc/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -240,46 +240,10 @@
clear_single_step(child);
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -451,10 +415,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/ppc64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/ppc64/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/ppc64/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -52,46 +52,10 @@
clear_single_step(child);
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -278,10 +242,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/sh/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/sh/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -80,48 +80,11 @@
/* nothing to do.. */
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int ret;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -289,10 +252,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/v850/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/v850/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/v850/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -113,45 +113,10 @@
return 1;
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int rval;
- lock_kernel();
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- rval = -EPERM;
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- rval = 0;
- goto out;
- }
- rval = -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;
-
- rval = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- rval = ptrace_attach(child);
- goto out_tsk;
- }
- rval = ptrace_check_attach(child, request == PTRACE_KILL);
- if (rval < 0)
- goto out_tsk;
-
switch (request) {
unsigned long val, copied;
@@ -249,10 +214,6 @@
goto out;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return rval;
}
Index: linux-2.6/arch/x86_64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/x86_64/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/x86_64/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -313,48 +313,11 @@
}
-asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, unsigned long addr, long data)
{
- struct task_struct *child;
long i, ret;
unsigned ui;
- /* This lock_kernel fixes a subtle race with suid exec */
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -608,10 +571,6 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/xtensa/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/xtensa/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/xtensa/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -45,58 +45,10 @@
/* Nothing to do.. */
}
-int sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret = -EPERM;
- lock_kernel();
-
-#if 0
- if ((int)request != 1)
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (unsigned long) data);
-#endif
-
- 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);
- 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);
- goto out_tsk;
- }
-
- if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@
ret = ptrace_request(child, request, addr, data);
goto out;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -388,3 +388,85 @@
return ret;
}
+
+#ifndef __ARCH_SYS_PTRACE
+static int ptrace_get_task_struct(long request, long pid,
+ struct task_struct **childp)
+{
+ struct task_struct *child;
+ int ret;
+
+ /*
+ * Callers use child == NULL as an indication to exit early even
+ * when the return value is 0, so make sure it is non-NULL here.
+ */
+ *childp = NULL;
+
+ if (request == PTRACE_TRACEME) {
+ /*
+ * Are we already being traced?
+ */
+ if (current->ptrace & PT_PTRACED)
+ return -EPERM;
+ ret = security_ptrace(current->parent, current);
+ if (ret)
+ return -EPERM;
+ /*
+ * Set the ptrace bit in the process ptrace flags.
+ */
+ current->ptrace |= PT_PTRACED;
+ return 0;
+ }
+
+ /*
+ * You may not mess with init
+ */
+ if (pid == 1)
+ return -EPERM;
+
+ ret = -ESRCH;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ return -ESRCH;
+
+ *childp = child;
+ return 0;
+}
+
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+{
+ struct task_struct *child;
+ long ret;
+
+ /*
+ * This lock_kernel fixes a subtle race with suid exec
+ */
+ lock_kernel();
+ ret = ptrace_get_task_struct(request, pid, &child);
+ if (!child)
+ goto out;
+
+ if (request == PTRACE_ATTACH) {
+ ret = ptrace_attach(child);
+ goto out;
+ }
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ ret = arch_ptrace(child, request, addr, data);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ out_put_task_struct:
+ put_task_struct(child);
+ out:
+ unlock_kernel();
+ return ret;
+}
+#endif /* __ARCH_SYS_PTRACE */
Index: linux-2.6/arch/cris/arch-v10/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v10/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/cris/arch-v10/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -76,55 +76,11 @@
* (in user space) where the result of the ptrace call is written (instead of
* being returned).
*/
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/cris/arch-v32/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v32/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/cris/arch-v32/kernel/ptrace.c 2005-08-24 11:37:13.000000000 +0200
@@ -99,55 +99,11 @@
}
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/um/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/um/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/um/kernel/ptrace.c 2005-08-24 11:37:14.000000000 +0200
@@ -43,53 +43,10 @@
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int i, ret;
- 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);
- 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;
- }
-
-#ifdef SUBACH_PTRACE_SPECIAL
- SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -282,10 +239,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
- out_tsk:
- put_task_struct(child);
- out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/include/asm-alpha/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-alpha/ptrace.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-alpha/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -67,6 +67,9 @@
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
Index: linux-2.6/include/asm-arm/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-arm/unistd.h 2005-08-24 11:34:25.000000000 +0200
+++ linux-2.6/include/asm-arm/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -542,7 +542,6 @@
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-arm26/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-arm26/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-arm26/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -480,7 +480,6 @@
asmlinkage int sys_fork(struct pt_regs *regs);
asmlinkage int sys_vfork(struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-cris/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-cris/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-cris/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -367,7 +367,6 @@
asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
long mof, long srp, struct pt_regs *regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-h8300/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-h8300/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-h8300/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -528,7 +528,6 @@
asmlinkage int sys_execve(char *name, char **argv, char **envp,
int dummy, ...);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-i386/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-i386/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-i386/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -448,7 +448,6 @@
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_vfork(struct pt_regs regs);
asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage long sys_iopl(unsigned long unused);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
Index: linux-2.6/include/asm-ia64/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-ia64/ptrace.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-ia64/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -227,6 +227,9 @@
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
/*
* We use the ia64_psr(regs)->ri to determine which of the three
* instructions in bundle (16 bytes) took the sample. Generate
Index: linux-2.6/include/asm-m32r/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-m32r/ptrace.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-m32r/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -145,6 +145,9 @@
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
#elif defined(CONFIG_ISA_M32R)
Index: linux-2.6/include/asm-m68knommu/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-m68knommu/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-m68knommu/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -504,7 +504,6 @@
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(char *name, char **argv, char **envp);
asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct pt_regs;
int sys_request_irq(unsigned int,
irqreturn_t (*)(int, void *, struct pt_regs *),
Index: linux-2.6/include/asm-mips/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-mips/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-mips/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -1164,7 +1164,6 @@
unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-parisc/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-parisc/ptrace.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-parisc/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -45,6 +45,9 @@
#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */
#ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE 1
+
+
/* XXX should we use iaoq[1] or iaoq[0] ? */
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
Index: linux-2.6/include/asm-ppc/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-ppc/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-ppc/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -469,7 +469,6 @@
int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
struct pt_regs *regs);
int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-ppc64/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-ppc64/unistd.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-ppc64/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -467,7 +467,6 @@
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs);
int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
long sys_rt_sigaction(int sig, const struct sigaction __user *act,
struct sigaction __user *oact, size_t sigsetsize);
Index: linux-2.6/include/asm-sh/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-sh/unistd.h 2005-08-24 11:34:25.000000000 +0200
+++ linux-2.6/include/asm-sh/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -503,7 +503,6 @@
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
size_t count, long dummy, loff_t pos);
asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
Index: linux-2.6/include/asm-sparc/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-sparc/ptrace.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-sparc/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -60,6 +60,9 @@
#define STACKFRAME_SZ sizeof(struct sparc_stackf)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
unsigned long profile_pc(struct pt_regs *);
Index: linux-2.6/include/asm-sparc64/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-sparc64/ptrace.h 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/include/asm-sparc64/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -94,6 +94,9 @@
#define STACKFRAME32_SZ sizeof(struct sparc_stackf32)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
Index: linux-2.6/include/asm-v850/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-v850/unistd.h 2005-08-14 12:03:17.000000000 +0200
+++ linux-2.6/include/asm-v850/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -452,7 +452,6 @@
struct pt_regs;
int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
int sys_pipe (int *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
Index: linux-2.6/include/asm-x86_64/unistd.h
===================================================================
--- linux-2.6.orig/include/asm-x86_64/unistd.h 2005-08-14 12:03:17.000000000 +0200
+++ linux-2.6/include/asm-x86_64/unistd.h 2005-08-24 11:37:14.000000000 +0200
@@ -780,8 +780,6 @@
#include <linux/types.h>
#include <asm/ptrace.h>
-asmlinkage long sys_ptrace(long request, long pid,
- unsigned long addr, long data);
asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
struct sigaction;
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h 2005-08-14 12:03:17.000000000 +0200
+++ linux-2.6/include/linux/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -76,6 +76,8 @@
#include <linux/compiler.h> /* For unlikely. */
#include <linux/sched.h> /* For struct task_struct. */
+
+extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
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);
Index: linux-2.6/arch/sh64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sh64/kernel/ptrace.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/sh64/kernel/ptrace.c 2005-08-24 11:44:32.000000000 +0200
@@ -28,6 +28,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
+#include <linux/syscalls.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -121,61 +122,11 @@
return 0;
}
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
- extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
-#define WPC_DBRMODE 0x0d104008
- static int first_call = 1;
int ret;
- lock_kernel();
-
- if (first_call) {
- /* Set WPC.DBRMODE to 0. This makes all debug events get
- * delivered through RESVEC, i.e. into the handlers in entry.S.
- * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
- * would normally be left set to 1, which makes debug events get
- * delivered through DBRVEC, i.e. into the remote gdb's
- * handlers. This prevents ptrace getting them, and confuses
- * the remote gdb.) */
- printk("DBRMODE set to 0 to permit native debugging\n");
- poke_real_address_q(WPC_DBRMODE, 0);
- first_call = 0;
- }
-
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
+asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+{
+ extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+#define WPC_DBRMODE 0x0d104008
+ static int first_call = 1;
+
+ lock_kernel();
+ if (first_call) {
+ /* Set WPC.DBRMODE to 0. This makes all debug events get
+ * delivered through RESVEC, i.e. into the handlers in entry.S.
+ * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
+ * would normally be left set to 1, which makes debug events get
+ * delivered through DBRVEC, i.e. into the remote gdb's
+ * handlers. This prevents ptrace getting them, and confuses
+ * the remote gdb.) */
+ printk("DBRMODE set to 0 to permit native debugging\n");
+ poke_real_address_q(WPC_DBRMODE, 0);
+ first_call = 0;
+ }
+ unlock_kernel();
+
+ return sys_ptrace(request, pid, addr, data);
+}
+
asmlinkage void syscall_trace(void)
{
struct task_struct *tsk = current;
Index: linux-2.6/arch/sh64/kernel/syscalls.S
===================================================================
--- linux-2.6.orig/arch/sh64/kernel/syscalls.S 2005-08-24 11:34:24.000000000 +0200
+++ linux-2.6/arch/sh64/kernel/syscalls.S 2005-08-24 11:37:14.000000000 +0200
@@ -46,7 +46,7 @@
.long sys_setuid16
.long sys_getuid16
.long sys_stime /* 25 */
- .long sys_ptrace
+ .long sh64_ptrace
.long sys_alarm
.long sys_fstat
.long sys_pause
Index: linux-2.6/include/asm-m68k/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-m68k/ptrace.h 2005-08-14 12:03:17.000000000 +0200
+++ linux-2.6/include/asm-m68k/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -65,6 +65,7 @@
#define PTRACE_SETFPREGS 15
#ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE 1
#ifndef PS_S
#define PS_S (0x2000)
Index: linux-2.6/include/asm-s390/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-s390/ptrace.h 2005-08-14 12:03:17.000000000 +0200
+++ linux-2.6/include/asm-s390/ptrace.h 2005-08-24 11:37:14.000000000 +0200
@@ -468,6 +468,8 @@
};
#ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define profile_pc(regs) instruction_pointer(regs)
Index: linux-2.6/arch/ia64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.orig/arch/ia64/ia32/sys_ia32.c 2005-08-14 12:03:16.000000000 +0200
+++ linux-2.6/arch/ia64/ia32/sys_ia32.c 2005-08-24 11:44:49.000000000 +0200
@@ -50,6 +50,7 @@
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/mman.h>
+#include <linux/syscalls.h>
#include <asm/intrinsics.h>
#include <asm/semaphore.h>
Index: linux-2.6/include/linux/syscalls.h
===================================================================
--- linux-2.6.orig/include/linux/syscalls.h 2005-08-11 16:46:06.000000000 +0200
+++ linux-2.6/include/linux/syscalls.h 2005-08-24 11:39:22.000000000 +0200
@@ -60,6 +60,7 @@
#include <asm/semaphore.h>
#include <asm/siginfo.h>
#include <asm/signal.h>
+#include <asm/ptrace.h> /* for __ARCH_SYS_PTRACE */
#include <linux/quota.h>
#include <linux/key.h>
@@ -477,6 +478,9 @@
unsigned long off, unsigned long len,
void __user *buf);
+#ifndef __ARCH_SYS_PTRACE
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
+#endif
asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5);
asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags);
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:09 [PATCH " Christoph Hellwig
@ 2005-11-01 5:12 ` Christoph Hellwig
2005-11-01 9:51 ` Norbert Kiesel
` (5 more replies)
0 siblings, 6 replies; 27+ messages in thread
From: Christoph Hellwig @ 2005-11-01 5:12 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-arch
On Tue, Nov 01, 2005 at 06:09:00AM +0100, Christoph Hellwig wrote:
> [Let's try again now that sys_ptrace returns long everywhere mainline..]
>
> The sys_ptrace boilerplate code (everything outside the big switch
> statement for the arch-specific requests) is shared by most
> architectures. This patch moves it to kernel/ptrace.c and leaves the
> arch-specific code as arch_ptrace.
>
> Some architectures have a too different ptrace so we have to exclude
> them. They continue to keep their implementations. For sh64 I had to
> add a sh64_ptrace wrapper because it does some initialization on the
> first call. For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block,
> but SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
Umm, it might be a good idea to actually send the current patch instead
of the old one. I really should write this text from scratch instead
of copying it :)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/arch/arm/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/ptrace.c 2005-10-31 13:15:47.000000000 +0100
+++ linux-2.6/arch/arm/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -648,7 +648,7 @@
#endif
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -782,53 +782,6 @@
return ret;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
Index: linux-2.6/arch/arm26/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/arm26/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/arm26/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -546,7 +546,7 @@
sizeof(struct user_fp)) ? -EFAULT : 0;
}
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
unsigned long tmp;
int ret;
@@ -665,53 +665,6 @@
return ret;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- return ret;
-}
-
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{
unsigned long ip;
Index: linux-2.6/arch/frv/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/frv/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/frv/kernel/ptrace.c 2005-10-31 17:31:24.000000000 +0100
@@ -106,48 +106,11 @@
child->thread.frame0->__status |= REG__STATUS_STEP;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
int ret;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/h8300/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/h8300/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/h8300/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -57,43 +57,10 @@
h8300_disable_trace(child);
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/i386/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/i386/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/i386/kernel/ptrace.c 2005-10-31 17:40:06.000000000 +0100
@@ -354,49 +354,12 @@
return 0;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int i, ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -663,10 +626,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out_tsk:
return ret;
}
Index: linux-2.6/arch/m68knommu/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m68knommu/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/m68knommu/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -101,43 +101,10 @@
put_reg(child, PT_SR, tmp);
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(truct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -357,10 +324,6 @@
ret = -EIO;
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/mips/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/mips/kernel/ptrace.c 2005-10-31 17:40:36.000000000 +0100
@@ -174,51 +174,10 @@
return 0;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
-#if 0
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -319,7 +278,7 @@
if (!cpu_has_dsp) {
tmp = 0;
ret = -EIO;
- goto out_tsk;
+ goto out;
}
if (child->thread.dsp.used_dsp) {
dregs = __get_dsp_regs(child);
@@ -333,14 +292,14 @@
if (!cpu_has_dsp) {
tmp = 0;
ret = -EIO;
- goto out_tsk;
+ goto out;
}
tmp = child->thread.dsp.dspcontrol;
break;
default:
tmp = 0;
ret = -EIO;
- goto out_tsk;
+ goto out;
}
ret = put_user(tmp, (unsigned long __user *) data);
break;
@@ -495,11 +454,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out:
return ret;
}
Index: linux-2.6/arch/sh/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/ptrace.c 2005-10-31 13:15:49.000000000 +0100
+++ linux-2.6/arch/sh/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -80,48 +80,11 @@
/* nothing to do.. */
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
struct user * dummy = NULL;
int ret;
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -289,10 +252,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/v850/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/v850/kernel/ptrace.c 2005-10-31 13:15:49.000000000 +0100
+++ linux-2.6/arch/v850/kernel/ptrace.c 2005-10-31 17:38:42.000000000 +0100
@@ -113,45 +113,10 @@
return 1;
}
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int rval;
- lock_kernel();
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- rval = -EPERM;
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- rval = 0;
- goto out;
- }
- rval = -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;
-
- rval = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- rval = ptrace_attach(child);
- goto out_tsk;
- }
- rval = ptrace_check_attach(child, request == PTRACE_KILL);
- if (rval < 0)
- goto out_tsk;
-
switch (request) {
unsigned long val, copied;
@@ -248,11 +213,7 @@
rval = -EIO;
goto out;
}
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out:
return rval;
}
Index: linux-2.6/arch/x86_64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/x86_64/kernel/ptrace.c 2005-10-31 12:23:20.000000000 +0100
+++ linux-2.6/arch/x86_64/kernel/ptrace.c 2005-10-31 17:38:52.000000000 +0100
@@ -313,48 +313,11 @@
}
-asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, unsigned long addr, long data)
{
- struct task_struct *child;
long i, ret;
unsigned ui;
- /* This lock_kernel fixes a subtle race with suid exec */
- 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);
- 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;
- }
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -608,10 +571,6 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
Index: linux-2.6/arch/xtensa/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/xtensa/kernel/ptrace.c 2005-10-31 13:15:49.000000000 +0100
+++ linux-2.6/arch/xtensa/kernel/ptrace.c 2005-10-31 17:39:06.000000000 +0100
@@ -45,58 +45,10 @@
/* Nothing to do.. */
}
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret = -EPERM;
- lock_kernel();
-
-#if 0
- if ((int)request != 1)
- printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
- (int) request, (int) pid, (unsigned long) addr,
- (unsigned long) data);
-#endif
-
- 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);
- 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);
- goto out_tsk;
- }
-
- if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@
ret = ptrace_request(child, request, addr, data);
goto out;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+ out:
return ret;
}
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-10-31 13:15:52.000000000 +0100
+++ linux-2.6/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -406,3 +406,85 @@
return ret;
}
+
+#ifndef __ARCH_SYS_PTRACE
+static int ptrace_get_task_struct(long request, long pid,
+ struct task_struct **childp)
+{
+ struct task_struct *child;
+ int ret;
+
+ /*
+ * Callers use child == NULL as an indication to exit early even
+ * when the return value is 0, so make sure it is non-NULL here.
+ */
+ *childp = NULL;
+
+ if (request == PTRACE_TRACEME) {
+ /*
+ * Are we already being traced?
+ */
+ if (current->ptrace & PT_PTRACED)
+ return -EPERM;
+ ret = security_ptrace(current->parent, current);
+ if (ret)
+ return -EPERM;
+ /*
+ * Set the ptrace bit in the process ptrace flags.
+ */
+ current->ptrace |= PT_PTRACED;
+ return 0;
+ }
+
+ /*
+ * You may not mess with init
+ */
+ if (pid == 1)
+ return -EPERM;
+
+ ret = -ESRCH;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ return -ESRCH;
+
+ *childp = child;
+ return 0;
+}
+
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+{
+ struct task_struct *child;
+ long ret;
+
+ /*
+ * This lock_kernel fixes a subtle race with suid exec
+ */
+ lock_kernel();
+ ret = ptrace_get_task_struct(request, pid, &child);
+ if (!child)
+ goto out;
+
+ if (request == PTRACE_ATTACH) {
+ ret = ptrace_attach(child);
+ goto out;
+ }
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ ret = arch_ptrace(child, request, addr, data);
+ if (ret < 0)
+ goto out_put_task_struct;
+
+ out_put_task_struct:
+ put_task_struct(child);
+ out:
+ unlock_kernel();
+ return ret;
+}
+#endif /* __ARCH_SYS_PTRACE */
Index: linux-2.6/arch/cris/arch-v10/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v10/kernel/ptrace.c 2005-10-31 12:23:04.000000000 +0100
+++ linux-2.6/arch/cris/arch-v10/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -76,55 +76,11 @@
* (in user space) where the result of the ptrace call is written (instead of
* being returned).
*/
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/cris/arch-v32/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v32/kernel/ptrace.c 2005-10-31 12:23:04.000000000 +0100
+++ linux-2.6/arch/cris/arch-v32/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -99,55 +99,11 @@
}
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int ret;
unsigned long __user *datap = (unsigned long __user *)data;
- 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);
-
- if (!child)
- goto out;
-
- ret = -EPERM;
-
- if (pid == 1) /* Leave the init process alone! */
- goto out_tsk;
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* Read word at location address. */
case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/arch/um/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/um/kernel/ptrace.c 2005-10-31 12:23:19.000000000 +0100
+++ linux-2.6/arch/um/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -43,53 +43,10 @@
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
int i, ret;
- 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);
- 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;
- }
-
-#ifdef SUBACH_PTRACE_SPECIAL
- SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -282,10 +239,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
- out_tsk:
- put_task_struct(child);
- out:
- unlock_kernel();
+
return ret;
}
Index: linux-2.6/include/asm-alpha/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-alpha/ptrace.h 2005-10-31 12:24:00.000000000 +0100
+++ linux-2.6/include/asm-alpha/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -67,6 +67,9 @@
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
Index: linux-2.6/include/asm-ia64/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-ia64/ptrace.h 2005-10-31 12:24:05.000000000 +0100
+++ linux-2.6/include/asm-ia64/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -229,6 +229,9 @@
};
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
/*
* We use the ia64_psr(regs)->ri to determine which of the three
* instructions in bundle (16 bytes) took the sample. Generate
Index: linux-2.6/include/asm-m32r/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-m32r/ptrace.h 2005-10-31 12:24:05.000000000 +0100
+++ linux-2.6/include/asm-m32r/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -145,6 +145,9 @@
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
#elif defined(CONFIG_ISA_M32R)
Index: linux-2.6/include/asm-sparc/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-sparc/ptrace.h 2005-10-31 12:24:12.000000000 +0100
+++ linux-2.6/include/asm-sparc/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -60,6 +60,9 @@
#define STACKFRAME_SZ sizeof(struct sparc_stackf)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
unsigned long profile_pc(struct pt_regs *);
Index: linux-2.6/include/asm-sparc64/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-sparc64/ptrace.h 2005-10-31 12:24:12.000000000 +0100
+++ linux-2.6/include/asm-sparc64/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -94,6 +94,9 @@
#define STACKFRAME32_SZ sizeof(struct sparc_stackf32)
#ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE 1
+
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h 2005-10-31 12:24:14.000000000 +0100
+++ linux-2.6/include/linux/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -78,6 +78,8 @@
#include <linux/compiler.h> /* For unlikely. */
#include <linux/sched.h> /* For struct task_struct. */
+
+extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
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);
Index: linux-2.6/arch/sh64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sh64/kernel/ptrace.c 2005-10-31 13:15:49.000000000 +0100
+++ linux-2.6/arch/sh64/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
@@ -28,6 +28,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
+#include <linux/syscalls.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -121,61 +122,11 @@
return 0;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
- extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
-#define WPC_DBRMODE 0x0d104008
- static int first_call = 1;
int ret;
- lock_kernel();
-
- if (first_call) {
- /* Set WPC.DBRMODE to 0. This makes all debug events get
- * delivered through RESVEC, i.e. into the handlers in entry.S.
- * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
- * would normally be left set to 1, which makes debug events get
- * delivered through DBRVEC, i.e. into the remote gdb's
- * handlers. This prevents ptrace getting them, and confuses
- * the remote gdb.) */
- printk("DBRMODE set to 0 to permit native debugging\n");
- poke_real_address_q(WPC_DBRMODE, 0);
- first_call = 0;
- }
-
- 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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
return ret;
}
+asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+{
+ extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+#define WPC_DBRMODE 0x0d104008
+ static int first_call = 1;
+
+ lock_kernel();
+ if (first_call) {
+ /* Set WPC.DBRMODE to 0. This makes all debug events get
+ * delivered through RESVEC, i.e. into the handlers in entry.S.
+ * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
+ * would normally be left set to 1, which makes debug events get
+ * delivered through DBRVEC, i.e. into the remote gdb's
+ * handlers. This prevents ptrace getting them, and confuses
+ * the remote gdb.) */
+ printk("DBRMODE set to 0 to permit native debugging\n");
+ poke_real_address_q(WPC_DBRMODE, 0);
+ first_call = 0;
+ }
+ unlock_kernel();
+
+ return sys_ptrace(request, pid, addr, data);
+}
+
asmlinkage void syscall_trace(void)
{
struct task_struct *tsk = current;
Index: linux-2.6/arch/sh64/kernel/syscalls.S
===================================================================
--- linux-2.6.orig/arch/sh64/kernel/syscalls.S 2005-10-31 12:23:19.000000000 +0100
+++ linux-2.6/arch/sh64/kernel/syscalls.S 2005-10-31 17:30:43.000000000 +0100
@@ -46,7 +46,7 @@
.long sys_setuid16
.long sys_getuid16
.long sys_stime /* 25 */
- .long sys_ptrace
+ .long sh64_ptrace
.long sys_alarm
.long sys_fstat
.long sys_pause
Index: linux-2.6/include/asm-s390/ptrace.h
===================================================================
--- linux-2.6.orig/include/asm-s390/ptrace.h 2005-10-31 12:24:12.000000000 +0100
+++ linux-2.6/include/asm-s390/ptrace.h 2005-10-31 17:30:43.000000000 +0100
@@ -468,6 +468,8 @@
};
#ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE 1
+
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define profile_pc(regs) instruction_pointer(regs)
Index: linux-2.6/arch/m68k/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m68k/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/m68k/kernel/ptrace.c 2005-10-31 17:33:38.000000000 +0100
@@ -121,48 +121,11 @@
child->thread.work.syscall_trace = 0;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
int i, ret = 0;
- lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- ret = -EPERM;
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- goto out;
- }
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (unlikely(!child)) {
- ret = -ESRCH;
- goto out;
- }
-
- /* you may not mess with init */
- if (unlikely(pid == 1)) {
- ret = -EPERM;
- goto out_tsk;
- }
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -317,14 +280,10 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
out_eio:
- ret = -EIO;
- goto out_tsk;
+ return -EIO;
}
asmlinkage void syscall_trace(void)
Index: linux-2.6/arch/parisc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/parisc/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/parisc/kernel/ptrace.c 2005-10-31 17:36:23.000000000 +0100
@@ -78,52 +78,13 @@
pa_psw(child)->l = 0;
}
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
long ret;
#ifdef DEBUG_PTRACE
long oaddr=addr, odata=data;
#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);
- 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);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
@@ -383,11 +344,11 @@
case PTRACE_GETEVENTMSG:
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
- goto out_tsk;
+ goto out;
default:
ret = ptrace_request(child, request, addr, data);
- goto out_tsk;
+ goto out;
}
out_wake_notrap:
@@ -396,10 +357,7 @@
wake_up_process(child);
ret = 0;
out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
- DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+ DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
request, pid, oaddr, odata, ret);
return ret;
}
Index: linux-2.6/arch/powerpc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/ptrace.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/powerpc/kernel/ptrace.c 2005-10-31 17:40:41.000000000 +0100
@@ -248,46 +248,10 @@
clear_single_step(child);
}
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
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);
- 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;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out_tsk;
-
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -540,10 +504,7 @@
ret = ptrace_request(child, request, addr, data);
break;
}
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
+
return ret;
}
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:12 ` Christoph Hellwig
@ 2005-11-01 9:51 ` Norbert Kiesel
2005-11-01 9:58 ` Paul Mackerras
` (4 subsequent siblings)
5 siblings, 0 replies; 27+ messages in thread
From: Norbert Kiesel @ 2005-11-01 9:51 UTC (permalink / raw)
To: linux-kernel
On Tue, 01 Nov 2005 06:12:21 +0100, Christoph Hellwig wrote:
<snip>
> Index: linux-2.6/kernel/ptrace.c
> ===================================================================
> --- linux-2.6.orig/kernel/ptrace.c 2005-10-31 13:15:52.000000000 +0100
> +++ linux-2.6/kernel/ptrace.c 2005-10-31 17:30:43.000000000 +0100
> @@ -406,3 +406,85 @@
>
> return ret;
> }
> +
> +#ifndef __ARCH_SYS_PTRACE
> +static int ptrace_get_task_struct(long request, long pid,
> + struct task_struct **childp)
> +{
> + struct task_struct *child;
> + int ret;
This "ret" is basically unused and should go away
> +
> + /*
> + * Callers use child == NULL as an indication to exit early even
> + * when the return value is 0, so make sure it is non-NULL here.
> + */
> + *childp = NULL;
> +
> + if (request == PTRACE_TRACEME) {
> + /*
> + * Are we already being traced?
> + */
> + if (current->ptrace & PT_PTRACED)
> + return -EPERM;
> + ret = security_ptrace(current->parent, current);
> + if (ret)
if (security_ptrace(current->parent, current))
> + return -EPERM;
> + /*
> + * Set the ptrace bit in the process ptrace flags.
> + */
> + current->ptrace |= PT_PTRACED;
> + return 0;
> + }
> +
> + /*
> + * You may not mess with init
> + */
> + if (pid == 1)
> + return -EPERM;
> +
> + ret = -ESRCH;
Not needed (anymore)
> + read_lock(&tasklist_lock);
> + child = find_task_by_pid(pid);
> + if (child)
> + get_task_struct(child);
> + read_unlock(&tasklist_lock);
> + if (!child)
> + return -ESRCH;
> +
> + *childp = child;
> + return 0;
> +}
> +
Best,
Norbert
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:12 ` Christoph Hellwig
2005-11-01 9:51 ` Norbert Kiesel
@ 2005-11-01 9:58 ` Paul Mackerras
2005-11-01 10:30 ` Ralf Baechle
` (3 subsequent siblings)
5 siblings, 0 replies; 27+ messages in thread
From: Paul Mackerras @ 2005-11-01 9:58 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
Christoph Hellwig writes:
> > Some architectures have a too different ptrace so we have to exclude
> > them. They continue to keep their implementations. For sh64 I had to
> > add a sh64_ptrace wrapper because it does some initialization on the
> > first call. For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block,
> > but SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
>
> Umm, it might be a good idea to actually send the current patch instead
> of the old one. I really should write this text from scratch instead
> of copying it :)
>
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Paul Mackerras <paulus@samba.org>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:12 ` Christoph Hellwig
2005-11-01 9:51 ` Norbert Kiesel
2005-11-01 9:58 ` Paul Mackerras
@ 2005-11-01 10:30 ` Ralf Baechle
2005-11-01 11:37 ` David Howells
` (2 subsequent siblings)
5 siblings, 0 replies; 27+ messages in thread
From: Ralf Baechle @ 2005-11-01 10:30 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Tue, Nov 01, 2005 at 06:12:21AM +0100, Christoph Hellwig wrote:
> Umm, it might be a good idea to actually send the current patch instead
> of the old one. I really should write this text from scratch instead
> of copying it :)
>
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: <ralf@linux-mips.org>
Ralf
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:12 ` Christoph Hellwig
` (2 preceding siblings ...)
2005-11-01 10:30 ` Ralf Baechle
@ 2005-11-01 11:37 ` David Howells
2005-11-02 4:31 ` Andrew Morton
2005-11-05 0:19 ` Christoph Hellwig
2005-11-01 18:12 ` Russell King
2005-11-02 11:21 ` Paul Mundt
5 siblings, 2 replies; 27+ messages in thread
From: David Howells @ 2005-11-01 11:37 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
Christoph Hellwig <hch@lst.de> wrote:
> > The sys_ptrace boilerplate code (everything outside the big switch
> > statement for the arch-specific requests) is shared by most
> > architectures. This patch moves it to kernel/ptrace.c and leaves the
> > arch-specific code as arch_ptrace.
Looks okay to me. I do have a concern about all the extra indirections we're
acquiring by this mad rush to centralise everything. It's going to slow things
down and consume more stack space. Is there any way we can:
(1) Make a sys_ptrace() *jump* to arch_ptrace() instead of calling it, thus
obviating the extra return step.
(2) Drop the use of lock_kernel().
Otherwise, the patch looks valid:
Acked-By: David Howells <dhowells@redhat.com>
David
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 11:37 ` David Howells
@ 2005-11-02 4:31 ` Andrew Morton
2005-11-11 20:45 ` Blaisorblade
2005-11-05 0:19 ` Christoph Hellwig
1 sibling, 1 reply; 27+ messages in thread
From: Andrew Morton @ 2005-11-02 4:31 UTC (permalink / raw)
To: David Howells; +Cc: hch, linux-kernel, linux-arch
David Howells <dhowells@redhat.com> wrote:
>
> Christoph Hellwig <hch@lst.de> wrote:
>
> > > The sys_ptrace boilerplate code (everything outside the big switch
> > > statement for the arch-specific requests) is shared by most
> > > architectures. This patch moves it to kernel/ptrace.c and leaves the
> > > arch-specific code as arch_ptrace.
>
> Looks okay to me. I do have a concern about all the extra indirections we're
> acquiring by this mad rush to centralise everything. It's going to slow things
> down and consume more stack space. Is there any way we can:
>
> (1) Make a sys_ptrace() *jump* to arch_ptrace() instead of calling it, thus
> obviating the extra return step.
>
> (2) Drop the use of lock_kernel().
If we can remove the lock_kernel() and move the final put_task_struct()
into each arch_ptrace() then we can end sys_ptrace() with
return arch_ptrace(....);
and with luck, gcc will convert it into a tailcall for us.
It's probably not the first place to start doing such optimisation tho.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH consolidate sys_ptrace
2005-11-02 4:31 ` Andrew Morton
@ 2005-11-11 20:45 ` Blaisorblade
0 siblings, 0 replies; 27+ messages in thread
From: Blaisorblade @ 2005-11-11 20:45 UTC (permalink / raw)
To: linux-kernel
Andrew Morton <akpm <at> osdl.org> writes:
>
> David Howells <dhowells <at> redhat.com> wrote:
> >
> > Christoph Hellwig <hch <at> lst.de> wrote:
> >
> > (1) Make a sys_ptrace() *jump* to arch_ptrace() instead of calling it, thus
> > obviating the extra return step.
> >
> If we can remove the lock_kernel() and move the final put_task_struct()
> into each arch_ptrace() then we can end sys_ptrace() with
> return arch_ptrace(....);
> and with luck, gcc will convert it into a tailcall for us.
Yep, it can do it, especially if CONFIG_REGPARM is enabled.
> It's probably not the first place to start doing such optimisation tho.
Boys, you risk being burned. I'm sorry I'll have to teach you a lesson. I'm
especially sorry because I had to learn it the hard way...
prevent_tail_call is there for a reason (grep for it in kernel/exit.c)
* If you do:
int do_foo(params...) {
...
}
asmlinkage int sys_foo(params...) {
return do_foo(a_new_param, params...);
}
* and do_foo and sys_foo have different prototypes (such as in the example or in
the patch),
THEN
GCC can reorder/change parameters of sys_foo on the stack, to make them match
the do_foo call.
Since those parameters are afterwards restored into userspace registers (which
are supposed to be unchanged), we get userspace breakage.
But only if userspace uses the registers afterwards, and if it calls with int
0x80 (there's no restoring otherwise, or something such).
I know this because I did once this exact error, and it was very hard to
diagnose (actually, it was in a UML-patch and I got breakage in UML). Also, it
was triggered only when CONFIG_REGPARM is enabled. If needed, I can point out
real examples (but you already should know).
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH consolidate sys_ptrace
2005-11-01 11:37 ` David Howells
2005-11-02 4:31 ` Andrew Morton
@ 2005-11-05 0:19 ` Christoph Hellwig
1 sibling, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2005-11-05 0:19 UTC (permalink / raw)
To: David Howells; +Cc: Christoph Hellwig, akpm, linux-kernel, linux-arch
On Tue, Nov 01, 2005 at 11:37:54AM +0000, David Howells wrote:
> Christoph Hellwig <hch@lst.de> wrote:
>
> > > The sys_ptrace boilerplate code (everything outside the big switch
> > > statement for the arch-specific requests) is shared by most
> > > architectures. This patch moves it to kernel/ptrace.c and leaves the
> > > arch-specific code as arch_ptrace.
>
> Looks okay to me. I do have a concern about all the extra indirections we're
> acquiring by this mad rush to centralise everything. It's going to slow things
> down and consume more stack space. Is there any way we can:
>
> (1) Make a sys_ptrace() *jump* to arch_ptrace() instead of calling it, thus
> obviating the extra return step.
>
> (2) Drop the use of lock_kernel().
>
> Otherwise, the patch looks valid:
As BKL usage indicates this is a real slowpath. No one cares about one
function call or less here.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:12 ` Christoph Hellwig
` (3 preceding siblings ...)
2005-11-01 11:37 ` David Howells
@ 2005-11-01 18:12 ` Russell King
2005-11-02 11:21 ` Paul Mundt
5 siblings, 0 replies; 27+ messages in thread
From: Russell King @ 2005-11-01 18:12 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
On Tue, Nov 01, 2005 at 06:12:21AM +0100, Christoph Hellwig wrote:
> On Tue, Nov 01, 2005 at 06:09:00AM +0100, Christoph Hellwig wrote:
> > [Let's try again now that sys_ptrace returns long everywhere mainline..]
> >
> > The sys_ptrace boilerplate code (everything outside the big switch
> > statement for the arch-specific requests) is shared by most
> > architectures. This patch moves it to kernel/ptrace.c and leaves the
> > arch-specific code as arch_ptrace.
> >
> > Some architectures have a too different ptrace so we have to exclude
> > them. They continue to keep their implementations. For sh64 I had to
> > add a sh64_ptrace wrapper because it does some initialization on the
> > first call. For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block,
> > but SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
>
> Umm, it might be a good idea to actually send the current patch instead
> of the old one. I really should write this text from scratch instead
> of copying it :)
>
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Thanks Christoph.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH consolidate sys_ptrace
2005-11-01 5:12 ` Christoph Hellwig
` (4 preceding siblings ...)
2005-11-01 18:12 ` Russell King
@ 2005-11-02 11:21 ` Paul Mundt
5 siblings, 0 replies; 27+ messages in thread
From: Paul Mundt @ 2005-11-02 11:21 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel, linux-arch
[-- Attachment #1: Type: text/plain, Size: 822 bytes --]
On Tue, Nov 01, 2005 at 06:12:21AM +0100, Christoph Hellwig wrote:
> On Tue, Nov 01, 2005 at 06:09:00AM +0100, Christoph Hellwig wrote:
> > Some architectures have a too different ptrace so we have to exclude
> > them. They continue to keep their implementations. For sh64 I had to
> > add a sh64_ptrace wrapper because it does some initialization on the
> > first call. For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block,
> > but SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
>
> Umm, it might be a good idea to actually send the current patch instead
> of the old one. I really should write this text from scratch instead
> of copying it :)
>
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
sh and sh64 bits look fine, thanks.
Acked-by: Paul Mundt <lethal@linux-sh.org>
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2005-11-11 20:48 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-10 8:00 [PATCH] consolidate sys_ptrace Christoph Hellwig
2005-08-10 8:33 ` Martin Schwidefsky
2005-08-10 8:38 ` Christoph Hellwig
2005-08-10 8:43 ` Andi Kleen
2005-08-10 9:36 ` David Howells
2005-08-10 12:46 ` Paul Mundt
2005-08-10 13:15 ` Ralf Baechle
2005-08-10 13:28 ` Jeff Dike
2005-08-10 17:08 ` Richard Henderson
2005-08-11 10:44 ` Roman Zippel
2005-08-11 13:51 ` Christoph Hellwig
2005-08-11 16:51 ` Russell King
2005-08-11 17:32 ` Richard Henderson
2005-08-11 17:33 ` Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2005-08-10 16:59 Luck, Tony
2005-08-11 0:20 ` Stephen Rothwell
2005-11-01 5:09 [PATCH " Christoph Hellwig
2005-11-01 5:12 ` Christoph Hellwig
2005-11-01 9:51 ` Norbert Kiesel
2005-11-01 9:58 ` Paul Mackerras
2005-11-01 10:30 ` Ralf Baechle
2005-11-01 11:37 ` David Howells
2005-11-02 4:31 ` Andrew Morton
2005-11-11 20:45 ` Blaisorblade
2005-11-05 0:19 ` Christoph Hellwig
2005-11-01 18:12 ` Russell King
2005-11-02 11:21 ` Paul Mundt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox