patch-2.1.23 linux/arch/m68k/kernel/ptrace.c
Next file: linux/arch/m68k/kernel/sys_m68k.c
Previous file: linux/arch/m68k/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 268
- Date:
Sun Jan 26 12:07:05 1997
- Orig file:
v2.1.22/linux/arch/m68k/kernel/ptrace.c
- Orig date:
Fri Nov 22 18:28:17 1996
diff -u --recursive --new-file v2.1.22/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
@@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
@@ -322,25 +324,29 @@
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
- struct user * dummy;
-
- dummy = NULL;
+ struct user * dummy = NULL;
+ int ret;
+ lock_kernel();
+ ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
if (current->flags & PF_PTRACED)
- return -EPERM;
+ goto out;
/* set the ptrace bit in the process flags. */
current->flags |= PF_PTRACED;
- return 0;
+ ret = 0;
+ goto out;
}
if (pid == 1) /* you may not mess with init */
- return -EPERM;
+ goto out;
+ ret = -ESRCH;
if (!(child = get_task(pid)))
- return -ESRCH;
+ goto out;
+ ret = -EPERM;
if (request == PTRACE_ATTACH) {
if (child == current)
- return -EPERM;
+ goto out;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
@@ -348,10 +354,10 @@
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid)) && !suser())
- return -EPERM;
+ goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
- return -EPERM;
+ goto out;
child->flags |= PF_PTRACED;
if (child->p_pptr != current) {
REMOVE_LINKS(child);
@@ -359,39 +365,42 @@
SET_LINKS(child);
}
send_sig(SIGSTOP, child, 1);
- return 0;
+ ret = 0;
+ goto out;
}
+ ret = -ESRCH;
if (!(child->flags & PF_PTRACED))
- return -ESRCH;
+ goto out;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
- return -ESRCH;
+ goto out;
}
if (child->p_pptr != current)
- return -ESRCH;
+ goto out;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
- int res;
- res = read_long(child, addr, &tmp);
- if (res < 0)
- return res;
- return put_user(tmp, (unsigned long *) data);
+ ret = read_long(child, addr, &tmp);
+ if (ret >= 0)
+ ret = put_user(tmp, (unsigned long *) data);
+ goto out;
}
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp;
+ ret = -EIO;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- return -EIO;
+ goto out;
tmp = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
+ ret = -EIO;
if (addr < 19) {
tmp = get_reg(child, addr);
if (addr == PT_SR)
@@ -400,23 +409,26 @@
else if (addr >= 21 && addr < 49)
tmp = child->tss.fp[addr - 21];
else
- return -EIO;
- return put_user(tmp,(unsigned long *) data);
+ goto out;
+ ret = put_user(tmp,(unsigned long *) data);
+ goto out;
}
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
- return write_long(child,addr,data);
+ ret = write_long(child,addr,data);
+ goto out;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ ret = -EIO;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- return -EIO;
+ goto out;
addr = addr >> 2; /* temporary hack. */
if (addr == PT_ORIG_D0)
- return -EIO;
+ goto out;
if (addr == PT_SR) {
data &= SR_MASK;
data <<= 16;
@@ -424,22 +436,24 @@
}
if (addr < 19) {
if (put_reg(child, addr, data))
- return -EIO;
- return 0;
+ goto out;
+ ret = 0;
+ goto out;
}
if (addr >= 21 && addr < 48)
{
child->tss.fp[addr - 21] = data;
- return 0;
+ ret = 0;
}
- return -EIO;
+ goto out;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
long tmp;
+ ret = -EIO;
if ((unsigned long) data >= NSIG)
- return -EIO;
+ goto out;
if (request == PTRACE_SYSCALL)
child->flags |= PF_TRACESYS;
else
@@ -449,7 +463,8 @@
/* make sure the single step bit is not set. */
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
- return 0;
+ ret = 0;
+ goto out;
}
/*
@@ -460,21 +475,23 @@
case PTRACE_KILL: {
long tmp;
+ ret = 0;
if (child->state == TASK_ZOMBIE) /* already dead */
- return 0;
+ goto out;
wake_up_process(child);
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
- return 0;
+ goto out;
}
case PTRACE_SINGLESTEP: { /* set the trap flag. */
long tmp;
+ ret = -EIO;
if ((unsigned long) data >= NSIG)
- return -EIO;
+ goto out;
child->flags &= ~PF_TRACESYS;
tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
@@ -482,14 +499,16 @@
wake_up_process(child);
child->exit_code = data;
/* give it a chance to run. */
- return 0;
+ ret = 0;
+ goto out;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
long tmp;
+ ret = -EIO;
if ((unsigned long) data >= NSIG)
- return -EIO;
+ goto out;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
wake_up_process(child);
child->exit_code = data;
@@ -499,19 +518,25 @@
/* make sure the single step bit is not set. */
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
- return 0;
+ ret = 0;
+ goto out;
}
default:
- return -EIO;
+ ret = -EIO;
+ goto out;
}
+out:
+ unlock_kernel();
+ return ret;
}
asmlinkage void syscall_trace(void)
{
+ lock_kernel();
if ((current->flags & (PF_PTRACED|PF_TRACESYS))
!= (PF_PTRACED|PF_TRACESYS))
- return;
+ goto out;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
notify_parent(current);
@@ -524,5 +549,6 @@
if (current->exit_code)
current->signal |= (1 << (current->exit_code - 1));
current->exit_code = 0;
- return;
+out:
+ unlock_kernel();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov