Skip to content

Commit

Permalink
[PATCH] use ptrace_get_task_struct in various places
Browse files Browse the repository at this point in the history
The ptrace_get_task_struct() helper that I added as part of the ptrace
consolidation is useful in variety of places that currently opencode it.
Switch them to the common helpers.

Add a ptrace_traceme() helper that needs to be explicitly called, and simplify
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.

Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Christoph Hellwig authored and Linus Torvalds committed Jan 9, 2006
1 parent 6b34350 commit 6b9c7ed
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 241 deletions.
24 changes: 5 additions & 19 deletions arch/alpha/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,30 +265,16 @@ do_sys_ptrace(long request, long pid, long addr, long data,
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);
Expand Down
16 changes: 5 additions & 11 deletions arch/ia64/ia32/sys_ia32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1761,21 +1761,15 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)

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);
Expand Down
9 changes: 1 addition & 8 deletions arch/ia64/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1422,14 +1422,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long 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;
current->ptrace |= PT_PTRACED;
ret = 0;
ret = ptrace_traceme();
goto out;
}

Expand Down
22 changes: 5 additions & 17 deletions arch/m32r/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,28 +762,16 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
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);
Expand Down
26 changes: 6 additions & 20 deletions arch/mips/kernel/ptrace32.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,16 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
(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);
Expand Down
28 changes: 7 additions & 21 deletions arch/powerpc/kernel/ptrace32.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,19 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
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;
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);
Expand Down
29 changes: 6 additions & 23 deletions arch/s390/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,35 +712,18 @@ sys_ptrace(long request, long pid, long addr, long data)
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();
Expand Down
35 changes: 6 additions & 29 deletions arch/sparc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,40 +286,17 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
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;
}

Expand Down
34 changes: 5 additions & 29 deletions arch/sparc64/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,39 +198,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
#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;
}

Expand Down
44 changes: 11 additions & 33 deletions arch/x86_64/ia32/ptrace32.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,36 +196,6 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val)

#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;
Expand Down Expand Up @@ -254,9 +224,16 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
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));

Expand Down Expand Up @@ -373,6 +350,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
break;
}

out:
put_task_struct(child);
return ret;
}
Expand Down
2 changes: 2 additions & 0 deletions include/linux/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 6b9c7ed

Please sign in to comment.