summaryrefslogtreecommitdiffstats
path: root/arch/mips64/kernel/ptrace.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-05-12 21:05:59 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-05-12 21:05:59 +0000
commitba2dacab305c598cd4c34a604f8e276bf5bab5ff (patch)
tree78670a0139bf4d5ace617b29b7eba82bbc74d602 /arch/mips64/kernel/ptrace.c
parentb77bf69998121e689c5e86cc5630d39a0a9ee6ca (diff)
Merge with Linux 2.3.99-pre7 and various other bits.
Diffstat (limited to 'arch/mips64/kernel/ptrace.c')
-rw-r--r--arch/mips64/kernel/ptrace.c76
1 files changed, 44 insertions, 32 deletions
diff --git a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c
index b79a61f0e..a0488107f 100644
--- a/arch/mips64/kernel/ptrace.c
+++ b/arch/mips64/kernel/ptrace.c
@@ -35,7 +35,6 @@
asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
{
struct task_struct *child;
- unsigned long flags;
int ret;
lock_kernel();
@@ -57,15 +56,19 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
ret = -ESRCH;
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!!! */
+ 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;
+ goto out_tsk;
+
if (request == PTRACE_ATTACH) {
if (child == current)
- goto out;
+ goto out_tsk;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
@@ -74,33 +77,33 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
- goto out;
+ goto out_tsk;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
- goto out;
+ goto out_tsk;
child->flags |= PF_PTRACED;
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
- write_unlock_irqrestore(&tasklist_lock, flags);
+ write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
- goto out;
+ goto out_tsk;
}
ret = -ESRCH;
if (!(child->flags & PF_PTRACED))
- goto out;
+ goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
- goto out;
+ goto out_tsk;
}
if (child->p_pptr != current)
- goto out;
+ goto out_tsk;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
@@ -113,7 +116,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
ret = -EIO;
if (copied != sizeof(tmp))
break;
- ret = put_user(tmp,(unsigned int *) data);
+ ret = put_user(tmp, (unsigned int *) data);
break;
}
@@ -174,10 +177,10 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
default:
tmp = 0;
ret = -EIO;
- goto out;
+ goto out_tsk;
}
ret = put_user(tmp, (unsigned *) data);
- goto out;
+ break;
}
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -273,11 +276,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
child->exit_code = data;
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
- write_unlock_irqrestore(&tasklist_lock, flags);
+ write_unlock_irq(&tasklist_lock);
wake_up_process(child);
ret = 0;
break;
@@ -287,6 +290,9 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
ret = -EIO;
break;
}
+
+out_tsk:
+ free_task_struct(child);
out:
unlock_kernel();
return ret;
@@ -295,7 +301,6 @@ out:
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
- unsigned long flags;
int ret;
lock_kernel();
@@ -317,15 +322,19 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -ESRCH;
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!!! */
+ 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) {
if (child == current)
- goto out;
+ goto out_tsk;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
@@ -334,33 +343,33 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
- goto out;
+ goto out_tsk;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
- goto out;
+ goto out_tsk;
child->flags |= PF_PTRACED;
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
- write_unlock_irqrestore(&tasklist_lock, flags);
+ write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
- goto out;
+ goto out_tsk;
}
ret = -ESRCH;
if (!(child->flags & PF_PTRACED))
- goto out;
+ goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
- goto out;
+ goto out_tsk;
}
if (child->p_pptr != current)
- goto out;
+ goto out_tsk;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
@@ -434,10 +443,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
default:
tmp = 0;
ret = -EIO;
- goto out;
+ goto out_tsk;
}
ret = put_user(tmp, (unsigned long *) data);
- goto out;
+ break;
}
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -533,11 +542,11 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
child->exit_code = data;
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
- write_unlock_irqrestore(&tasklist_lock, flags);
+ write_unlock_irq(&tasklist_lock);
wake_up_process(child);
ret = 0;
break;
@@ -547,6 +556,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
break;
}
+
+out_tsk:
+ free_task_struct(child);
out:
unlock_kernel();
return ret;