* [PATCH] use ptrace_get_task_struct in various places
@ 2005-11-08 5:30 Christoph Hellwig
2005-11-08 6:11 ` Andrew Morton
0 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2005-11-08 5:30 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel
The ptrace_get_task_struct() helper that I added as part of the ptrace
consolidation is usefull in variety of places that currently opencode
it. Switch them to the common helper.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/arch/alpha/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/ptrace.c 2005-10-31 17:50:44.000000000 +0100
+++ linux-2.6/arch/alpha/kernel/ptrace.c 2005-11-06 21:33:58.000000000 +0100
@@ -265,28 +265,7 @@
lock_kernel();
DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
request, pid, addr, data));
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out_notsk;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out_notsk;
- /* set the ptrace bit in the process ptrace flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out_notsk;
- }
- if (pid == 1) /* you may not mess with init */
- goto out_notsk;
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out_notsk;
Index: linux-2.6/arch/ia64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.orig/arch/ia64/ia32/sys_ia32.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/ia64/ia32/sys_ia32.c 2005-11-06 21:33:58.000000000 +0100
@@ -1760,22 +1760,9 @@
long i, ret;
lock_kernel();
- if (request == PTRACE_TRACEME) {
- ret = sys_ptrace(request, pid, addr, data);
- goto out;
- }
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
if (request == PTRACE_ATTACH) {
ret = sys_ptrace(request, pid, addr, data);
Index: linux-2.6/arch/m32r/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/ptrace.c 2005-10-31 17:50:44.000000000 +0100
+++ linux-2.6/arch/m32r/kernel/ptrace.c 2005-11-06 21:33:58.000000000 +0100
@@ -762,29 +762,10 @@
int ret;
lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out;
-
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
if (ret == 0)
Index: linux-2.6/arch/mips/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace32.c 2005-10-31 12:23:12.000000000 +0100
+++ linux-2.6/arch/mips/kernel/ptrace32.c 2005-11-06 21:33:58.000000000 +0100
@@ -57,31 +57,10 @@
(unsigned long) data);
#endif
lock_kernel();
- ret = -EPERM;
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- if ((ret = security_ptrace(current->parent, current)))
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
goto out_tsk;
Index: linux-2.6/arch/s390/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/ptrace.c 2005-10-31 17:50:44.000000000 +0100
+++ linux-2.6/arch/s390/kernel/ptrace.c 2005-11-06 21:33:58.000000000 +0100
@@ -712,36 +712,11 @@
int ret;
lock_kernel();
-
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- ret = -EPERM;
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- goto out;
+ ret = ptrace_get_task_struct(request, pid, &child);
+ if (child) {
+ ret = do_ptrace(child, request, addr, data);
+ put_task_struct(child);
}
-
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out;
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
- goto out;
-
- ret = do_ptrace(child, request, addr, data);
-
- put_task_struct(child);
out:
unlock_kernel();
return ret;
Index: linux-2.6/arch/sparc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/ptrace.c 2005-10-31 17:50:44.000000000 +0100
+++ linux-2.6/arch/sparc/kernel/ptrace.c 2005-11-06 21:33:58.000000000 +0100
@@ -286,40 +286,13 @@
s, (int) request, (int) pid, addr, data, addr2);
}
#endif
- if (request == PTRACE_TRACEME) {
- int my_ret;
-
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- pt_error_return(regs, EPERM);
- goto out;
- }
- my_ret = security_ptrace(current->parent, current);
- if (my_ret) {
- pt_error_return(regs, -my_ret);
- goto out;
- }
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- pt_succ_return(regs, 0);
- goto out;
- }
-#ifndef ALLOW_INIT_TRACING
- if (pid == 1) {
- /* Can't dork with init. */
- pt_error_return(regs, EPERM);
- goto out;
- }
-#endif
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child) {
- pt_error_return(regs, ESRCH);
+ if (ret)
+ pt_error_return(regs, -ret);
+ else
+ pt_succ_return(regs, 0);
goto out;
}
Index: linux-2.6/arch/sparc64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc64/kernel/ptrace.c 2005-10-31 17:50:44.000000000 +0100
+++ linux-2.6/arch/sparc64/kernel/ptrace.c 2005-11-06 21:33:58.000000000 +0100
@@ -197,40 +197,12 @@
s, request, pid, addr, data, addr2);
}
#endif
- if (request == PTRACE_TRACEME) {
- int ret;
-
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- pt_error_return(regs, EPERM);
- goto out;
- }
- ret = security_ptrace(current->parent, current);
- if (ret) {
- pt_error_return(regs, -ret);
- goto out;
- }
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- pt_succ_return(regs, 0);
- goto out;
- }
-#ifndef ALLOW_INIT_TRACING
- if (pid == 1) {
- /* Can't dork with init. */
- pt_error_return(regs, EPERM);
- goto out;
- }
-#endif
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
-
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child) {
- pt_error_return(regs, ESRCH);
+ if (ret)
+ pt_error_return(regs, -ret);
+ else
+ pt_succ_return(regs, 0);
goto out;
}
Index: linux-2.6/arch/x86_64/ia32/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/x86_64/ia32/ptrace32.c 2005-10-31 12:23:19.000000000 +0100
+++ linux-2.6/arch/x86_64/ia32/ptrace32.c 2005-11-06 21:33:58.000000000 +0100
@@ -196,36 +196,6 @@
#undef R32
-static struct task_struct *find_target(int request, int pid, int *err)
-{
- struct task_struct *child;
-
- *err = -EPERM;
- if (pid == 1)
- return NULL;
-
- *err = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (child) {
- *err = -EPERM;
- if (child->pid == 1)
- goto out;
- *err = ptrace_check_attach(child, request == PTRACE_KILL);
- if (*err < 0)
- goto out;
- return child;
- }
- out:
- if (child)
- put_task_struct(child);
- return NULL;
-
-}
-
asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
{
struct task_struct *child;
@@ -254,10 +224,14 @@
break;
}
- child = find_target(request, pid, &ret);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
return ret;
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out;
+
childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs));
switch (request) {
@@ -373,6 +347,7 @@
break;
}
+ out:
put_task_struct(child);
return ret;
}
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-11-06 21:33:53.000000000 +0100
+++ linux-2.6/kernel/ptrace.c 2005-11-06 21:33:58.000000000 +0100
@@ -407,9 +407,7 @@
return ret;
}
-#ifndef __ARCH_SYS_PTRACE
-static int ptrace_get_task_struct(long request, long pid,
- struct task_struct **childp)
+int ptrace_get_task_struct(long request, long pid, struct task_struct **childp)
{
struct task_struct *child;
int ret;
@@ -455,6 +453,7 @@
return 0;
}
+#ifndef __ARCH_SYS_PTRACE
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h 2005-11-06 21:33:53.000000000 +0100
+++ linux-2.6/include/linux/ptrace.h 2005-11-06 21:33:58.000000000 +0100
@@ -80,6 +80,7 @@
extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
+extern int ptrace_get_task_struct(long request, long pid, struct task_struct **childp);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
extern int ptrace_attach(struct task_struct *tsk);
Index: linux-2.6/arch/powerpc/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/ptrace32.c 2005-10-31 13:15:48.000000000 +0100
+++ linux-2.6/arch/powerpc/kernel/ptrace32.c 2005-11-06 21:35:45.000000000 +0100
@@ -44,34 +44,13 @@
unsigned long data)
{
struct task_struct *child;
- int ret = -EPERM;
+ int ret;
lock_kernel();
- if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
- goto out;
- }
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
+ ret = ptrace_get_task_struct(request, pid, &child);
if (!child)
goto out;
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out_tsk;
-
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
goto out_tsk;
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] use ptrace_get_task_struct in various places
2005-11-08 5:30 [PATCH] use ptrace_get_task_struct in various places Christoph Hellwig
@ 2005-11-08 6:11 ` Andrew Morton
2005-11-08 16:51 ` David S. Miller
2005-11-10 23:27 ` Christoph Hellwig
0 siblings, 2 replies; 6+ messages in thread
From: Andrew Morton @ 2005-11-08 6:11 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-kernel, William Lee Irwin III, David S. Miller
Christoph Hellwig <hch@lst.de> wrote:
>
> The ptrace_get_task_struct() helper that I added as part of the ptrace
> consolidation is usefull in variety of places that currently opencode
> it. Switch them to the common helper.
If we're going to export ptrace_get_task_struct() to the world it would be
nice to document it too - things like returning zero and a NULL *childp is
a little obscure.
The change breaks ALLOW_INIT_TRACING in sparc32 and sparc64. I don't know
if that matters. If (presumably) not, there are cleanups left over.
In arch/ia64/ia32/sys_ia32.c this patch will cause PTRACE_TRACEME requests
to be handled by ptrace_request() rather than by sys_ptrace(), which is a
not-obviously-correct change.
Was the omission of arch/ia64/kernel/ptrace.c:sys_ptrace() deliberate?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] use ptrace_get_task_struct in various places
2005-11-08 6:11 ` Andrew Morton
@ 2005-11-08 16:51 ` David S. Miller
2005-11-10 23:27 ` Christoph Hellwig
1 sibling, 0 replies; 6+ messages in thread
From: David S. Miller @ 2005-11-08 16:51 UTC (permalink / raw)
To: akpm; +Cc: hch, linux-kernel, wli
From: Andrew Morton <akpm@osdl.org>
Date: Mon, 7 Nov 2005 22:11:49 -0800
> The change breaks ALLOW_INIT_TRACING in sparc32 and sparc64. I don't know
> if that matters. If (presumably) not, there are cleanups left over.
You can kill that ALLOW_INIT_TRACING crap.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] use ptrace_get_task_struct in various places
2005-11-08 6:11 ` Andrew Morton
2005-11-08 16:51 ` David S. Miller
@ 2005-11-10 23:27 ` Christoph Hellwig
2005-11-11 0:00 ` Andrew Morton
1 sibling, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2005-11-10 23:27 UTC (permalink / raw)
To: Andrew Morton
Cc: Christoph Hellwig, linux-kernel, William Lee Irwin III,
David S. Miller
On Mon, Nov 07, 2005 at 10:11:49PM -0800, Andrew Morton wrote:
> Christoph Hellwig <hch@lst.de> wrote:
> >
> > The ptrace_get_task_struct() helper that I added as part of the ptrace
> > consolidation is usefull in variety of places that currently opencode
> > it. Switch them to the common helper.
>
> If we're going to export ptrace_get_task_struct() to the world it would be
> nice to document it too - things like returning zero and a NULL *childp is
> a little obscure.
done, patch below.
> In arch/ia64/ia32/sys_ia32.c this patch will cause PTRACE_TRACEME requests
> to be handled by ptrace_request()
you mean ptrace_get_task_struct?
> rather than by sys_ptrace(), which is a
> not-obviously-correct change.
sys_ptrace has the same code for it, in fact just about every ptrace
implementation uses ptrace_get_task_struct to handle that code,
but ptrace_get_task_struct can't be used by ia64 because some oddness
in the !PTRACE_TRACEME codepath.
> Was the omission of arch/ia64/kernel/ptrace.c:sys_ptrace() deliberate?
yes. it has some oddness about finding the 'right' task_struct of a
multi-threaded process.
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-11-10 15:36:12.000000000 +0100
+++ linux-2.6/kernel/ptrace.c 2005-11-10 15:46:05.000000000 +0100
@@ -407,6 +407,23 @@
return ret;
}
+/**
+ * ptrace_get_task_struct -- grab a task struct reference for ptrace
+ * @long: ptrace request type
+ * @pid: process to work on
+ * @childp: task struct returned
+ *
+ * This function is a helper for ptrace implementations. It checks
+ * permissions and then grabs a task struct for use of the actual
+ * ptrace implementation. As a special case also handles PTRACE_TRACEME
+ * completely (as it's trivial and doesn't need a task_struct reference.
+ *
+ * The calling convention is a little bit odd: negative return value
+ * means failure, positive one sucess. But even when this function
+ * suceeds @childp can be NULL and the calling ptrace implementation
+ * should return sucessfully immediately afterwards. This is to support
+ * the PTRACE_TRACEME special case.
+ */
int ptrace_get_task_struct(long request, long pid, struct task_struct **childp)
{
struct task_struct *child;
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] use ptrace_get_task_struct in various places
2005-11-10 23:27 ` Christoph Hellwig
@ 2005-11-11 0:00 ` Andrew Morton
2005-11-11 8:21 ` Christoph Hellwig
0 siblings, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2005-11-11 0:00 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: hch, linux-kernel, wli, davem
Christoph Hellwig <hch@lst.de> wrote:
>
> > In arch/ia64/ia32/sys_ia32.c this patch will cause PTRACE_TRACEME requests
> > to be handled by ptrace_request()
>
> you mean ptrace_get_task_struct?
No, I was referring to this code:
asmlinkage long
sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
{
struct task_struct *child;
unsigned int value, tmp;
long i, ret;
lock_kernel();
if (request == PTRACE_TRACEME) {
ret = sys_ptrace(request, pid, addr, data);
goto out;
}
Your patch removes the PTRACE_TRACEME special-case. Consequently
sys32_ptrace() will fall all the way down to the default: case of the
switch statement and will use ptrace_request() instead. And
ptrace_request() doesn't handle PTRACE_TRACEME, so I think it's busted.
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] use ptrace_get_task_struct in various places
2005-11-11 0:00 ` Andrew Morton
@ 2005-11-11 8:21 ` Christoph Hellwig
0 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2005-11-11 8:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: Christoph Hellwig, linux-kernel, wli, davem
On Thu, Nov 10, 2005 at 04:00:01PM -0800, Andrew Morton wrote:
> Christoph Hellwig <hch@lst.de> wrote:
> >
> > > In arch/ia64/ia32/sys_ia32.c this patch will cause PTRACE_TRACEME requests
> > > to be handled by ptrace_request()
> >
> > you mean ptrace_get_task_struct?
>
> No, I was referring to this code:
>
> asmlinkage long
> sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
> {
> struct task_struct *child;
> unsigned int value, tmp;
> long i, ret;
>
> lock_kernel();
> if (request == PTRACE_TRACEME) {
> ret = sys_ptrace(request, pid, addr, data);
> goto out;
> }
>
> Your patch removes the PTRACE_TRACEME special-case. Consequently
> sys32_ptrace() will fall all the way down to the default: case of the
> switch statement and will use ptrace_request() instead. And
> ptrace_request() doesn't handle PTRACE_TRACEME, so I think it's busted.
But ptrace_get_task_struct deals with PTRACE_TRACEME, as the comment
patch explains ;-)
But after trying to write up the complicated calling convetions and this
thread I've decided that this is not a good interface. So below there's
a new patch, that adds a ptrace_traceme() helper instead that needs to
be explicitly called, and simplifies the ptrace_get_task_struct
interface, we don't need the request argument now, and we return the
task_struct directly, using ERR_PTR() for error returns. It's a bit
more code in the callers, but we have two sane routines that do one
thing well now.
Index: linux-2.6/arch/alpha/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/ptrace.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/alpha/kernel/ptrace.c 2005-11-11 00:08:15.000000000 +0100
@@ -265,30 +265,16 @@
lock_kernel();
DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
request, pid, addr, data));
- ret = -EPERM;
if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
- goto out_notsk;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out_notsk;
- /* set the ptrace bit in the process ptrace flags. */
- current->ptrace |= PT_PTRACED;
- ret = 0;
+ ret = ptrace_traceme();
goto out_notsk;
}
- if (pid == 1) /* you may not mess with init */
- goto out_notsk;
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
goto out_notsk;
+ }
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
Index: linux-2.6/arch/ia64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.orig/arch/ia64/ia32/sys_ia32.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/ia64/ia32/sys_ia32.c 2005-11-11 00:07:39.000000000 +0100
@@ -1761,21 +1761,15 @@
lock_kernel();
if (request == PTRACE_TRACEME) {
- ret = sys_ptrace(request, pid, addr, data);
+ ret = ptrace_traceme();
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)
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
goto out;
- ret = -EPERM;
- if (pid == 1) /* no messing around with init! */
- goto out_tsk;
+ }
if (request == PTRACE_ATTACH) {
ret = sys_ptrace(request, pid, addr, data);
Index: linux-2.6/arch/m32r/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/ptrace.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/m32r/kernel/ptrace.c 2005-11-11 00:07:44.000000000 +0100
@@ -762,28 +762,16 @@
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;
+ ret = ptrace_traceme();
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 */
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
goto out;
+ }
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
Index: linux-2.6/arch/mips/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace32.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/mips/kernel/ptrace32.c 2005-11-11 00:07:48.000000000 +0100
@@ -57,30 +57,16 @@
(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;
+ ret = ptrace_traceme();
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;
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
+ goto out;
+ }
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
Index: linux-2.6/arch/s390/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/ptrace.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/s390/kernel/ptrace.c 2005-11-11 00:07:53.000000000 +0100
@@ -712,35 +712,18 @@
int ret;
lock_kernel();
-
if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- ret = -EPERM;
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- goto out;
+ ret = ptrace_traceme();
+ 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)
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
goto out;
+ }
ret = do_ptrace(child, request, addr, data);
-
put_task_struct(child);
out:
unlock_kernel();
Index: linux-2.6/arch/sparc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/ptrace.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/sparc/kernel/ptrace.c 2005-11-11 00:07:58.000000000 +0100
@@ -286,40 +286,17 @@
s, (int) request, (int) pid, addr, data, addr2);
}
#endif
- if (request == PTRACE_TRACEME) {
- int my_ret;
-
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- pt_error_return(regs, EPERM);
- goto out;
- }
- my_ret = security_ptrace(current->parent, current);
- if (my_ret) {
- pt_error_return(regs, -my_ret);
- goto out;
- }
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
+ if (request == PTRACE_TRACEME) {
+ ret = ptrace_traceme();
pt_succ_return(regs, 0);
goto out;
}
-#ifndef ALLOW_INIT_TRACING
- if (pid == 1) {
- /* Can't dork with init. */
- pt_error_return(regs, EPERM);
- goto out;
- }
-#endif
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child) {
- pt_error_return(regs, ESRCH);
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
+ pt_error_return(regs, -ret);
goto out;
}
Index: linux-2.6/arch/sparc64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc64/kernel/ptrace.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/sparc64/kernel/ptrace.c 2005-11-11 00:08:03.000000000 +0100
@@ -198,39 +198,15 @@
}
#endif
if (request == PTRACE_TRACEME) {
- int ret;
-
- /* are we already being traced? */
- if (current->ptrace & PT_PTRACED) {
- pt_error_return(regs, EPERM);
- goto out;
- }
- ret = security_ptrace(current->parent, current);
- if (ret) {
- pt_error_return(regs, -ret);
- goto out;
- }
-
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
+ ret = ptrace_traceme();
pt_succ_return(regs, 0);
goto out;
}
-#ifndef ALLOW_INIT_TRACING
- if (pid == 1) {
- /* Can't dork with init. */
- pt_error_return(regs, EPERM);
- goto out;
- }
-#endif
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child) {
- pt_error_return(regs, ESRCH);
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
+ pt_error_return(regs, -ret);
goto out;
}
Index: linux-2.6/arch/x86_64/ia32/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/x86_64/ia32/ptrace32.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/x86_64/ia32/ptrace32.c 2005-11-11 00:08:08.000000000 +0100
@@ -196,36 +196,6 @@
#undef R32
-static struct task_struct *find_target(int request, int pid, int *err)
-{
- struct task_struct *child;
-
- *err = -EPERM;
- if (pid == 1)
- return NULL;
-
- *err = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (child) {
- *err = -EPERM;
- if (child->pid == 1)
- goto out;
- *err = ptrace_check_attach(child, request == PTRACE_KILL);
- if (*err < 0)
- goto out;
- return child;
- }
- out:
- if (child)
- put_task_struct(child);
- return NULL;
-
-}
-
asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
{
struct task_struct *child;
@@ -254,9 +224,16 @@
break;
}
- child = find_target(request, pid, &ret);
- if (!child)
- return ret;
+ if (request == PTRACE_TRACEME)
+ return ptrace_traceme();
+
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ return PTR_ERR(child);
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
+ goto out;
childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs));
@@ -373,6 +350,7 @@
break;
}
+ out:
put_task_struct(child);
return ret;
}
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/kernel/ptrace.c 2005-11-11 00:10:29.000000000 +0100
@@ -407,54 +407,62 @@
return ret;
}
-#ifndef __ARCH_SYS_PTRACE
-static int ptrace_get_task_struct(long request, long pid,
- struct task_struct **childp)
+/**
+ * ptrace_traceme -- helper for PTRACE_TRACEME
+ *
+ * Performs checks and sets PT_PTRACED.
+ * Should be used by all ptrace implementations for PTRACE_TRACEME.
+ */
+int ptrace_traceme(void)
{
- 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.
+ * 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.
*/
- *childp = NULL;
+ current->ptrace |= PT_PTRACED;
+ return 0;
+}
- 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;
- }
+/**
+ * ptrace_get_task_struct -- grab a task struct reference for ptrace
+ * @pid: process id to grab a task_struct reference of
+ *
+ * This function is a helper for ptrace implementations. It checks
+ * permissions and then grabs a task struct for use of the actual
+ * ptrace implementation.
+ *
+ * Returns the task_struct for @pid or an ERR_PTR() on failure.
+ */
+struct task_struct *ptrace_get_task_struct(pid_t pid)
+{
+ struct task_struct *child;
/*
- * You may not mess with init
+ * Tracing init is not allowed.
*/
if (pid == 1)
- return -EPERM;
+ return ERR_PTR(-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 ERR_PTR(-ESRCH);
return 0;
}
+#ifndef __ARCH_SYS_PTRACE
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -464,9 +472,16 @@
* This lock_kernel fixes a subtle race with suid exec
*/
lock_kernel();
- ret = ptrace_get_task_struct(request, pid, &child);
- if (!child)
+ if (request == PTRACE_TRACEME) {
+ ret = ptrace_traceme();
goto out;
+ }
+
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
+ goto out;
+ }
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/include/linux/ptrace.h 2005-11-11 00:07:24.000000000 +0100
@@ -80,6 +80,8 @@
extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
+extern struct task_struct *ptrace_get_task_struct(pid_t pid);
+extern int ptrace_traceme(void);
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/powerpc/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/ptrace32.c 2005-11-10 16:02:04.000000000 +0100
+++ linux-2.6/arch/powerpc/kernel/ptrace32.c 2005-11-11 00:10:44.000000000 +0100
@@ -44,33 +44,19 @@
unsigned long data)
{
struct task_struct *child;
- int ret = -EPERM;
+ int ret;
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;
+ if (request == PTRACE_TRACEME) {=
+ ret = ptrace_traceme();
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;
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
+ goto out;
+ }
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
Index: linux-2.6/arch/ia64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/ptrace.c 2005-10-31 17:50:44.000000000 +0100
+++ linux-2.6/arch/ia64/kernel/ptrace.c 2005-11-10 23:54:14.000000000 +0100
@@ -1422,14 +1422,7 @@
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;
- current->ptrace |= PT_PTRACED;
- ret = 0;
+ ret = ptrace_traceme();
goto out;
}
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-11-11 8:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-08 5:30 [PATCH] use ptrace_get_task_struct in various places Christoph Hellwig
2005-11-08 6:11 ` Andrew Morton
2005-11-08 16:51 ` David S. Miller
2005-11-10 23:27 ` Christoph Hellwig
2005-11-11 0:00 ` Andrew Morton
2005-11-11 8:21 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox