patch-2.4.6 linux/arch/m68k/kernel/ptrace.c
Next file: linux/arch/m68k/kernel/setup.c
Previous file: linux/arch/m68k/kernel/head.S
Back to the patch index
Back to the overall index
- Lines: 284
- Date:
Mon Jun 11 19:15:27 2001
- Orig file:
v2.4.5/linux/arch/m68k/kernel/ptrace.c
- Orig date:
Mon Nov 27 18:02:06 2000
diff -u --recursive --new-file v2.4.5/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
@@ -107,15 +107,19 @@
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) ||
@@ -124,10 +128,10 @@
(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->ptrace & PT_PTRACED)
- goto out;
+ goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
@@ -140,17 +144,17 @@
send_sig(SIGSTOP, child, 1);
ret = 0;
- goto out;
+ goto out_tsk;
}
ret = -ESRCH;
if (!(child->ptrace & PT_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. */
@@ -162,9 +166,9 @@
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
- goto out;
+ break;
ret = put_user(tmp,(unsigned long *) data);
- goto out;
+ break;
}
/* read the word at location addr in the USER area. */
@@ -172,8 +176,9 @@
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- goto out;
+ if ((addr & 3) || addr < 0 ||
+ addr > sizeof(struct user) - 3)
+ break;
tmp = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
@@ -193,9 +198,9 @@
((tmp & 0x0000ffff) << 16);
#endif
} else
- goto out;
+ break;
ret = put_user(tmp,(unsigned long *) data);
- goto out;
+ break;
}
/* when I and D space are separate, this will have to be fixed. */
@@ -203,14 +208,15 @@
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
- goto out;
+ break;
ret = -EIO;
- goto out;
+ break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- goto out;
+ if ((addr & 3) || addr < 0 ||
+ addr > sizeof(struct user) - 3)
+ break;
addr = addr >> 2; /* temporary hack. */
@@ -221,9 +227,9 @@
}
if (addr < 19) {
if (put_reg(child, addr, data))
- goto out;
+ break;
ret = 0;
- goto out;
+ break;
}
if (addr >= 21 && addr < 48)
{
@@ -240,7 +246,7 @@
child->thread.fp[addr - 21] = data;
ret = 0;
}
- goto out;
+ break;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
@@ -248,7 +254,7 @@
ret = -EIO;
if ((unsigned long) data > _NSIG)
- goto out;
+ break;
if (request == PTRACE_SYSCALL)
child->ptrace |= PT_TRACESYS;
else
@@ -259,7 +265,7 @@
put_reg(child, PT_SR, tmp);
wake_up_process(child);
ret = 0;
- goto out;
+ break;
}
/*
@@ -272,13 +278,13 @@
ret = 0;
if (child->state == TASK_ZOMBIE) /* already dead */
- goto out;
+ break;
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);
wake_up_process(child);
- goto out;
+ break;
}
case PTRACE_SINGLESTEP: { /* set the trap flag. */
@@ -286,7 +292,7 @@
ret = -EIO;
if ((unsigned long) data > _NSIG)
- goto out;
+ break;
child->ptrace &= ~PT_TRACESYS;
tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
@@ -295,7 +301,7 @@
/* give it a chance to run. */
wake_up_process(child);
ret = 0;
- goto out;
+ break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
@@ -303,7 +309,7 @@
ret = -EIO;
if ((unsigned long) data > _NSIG)
- goto out;
+ break;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
@@ -316,7 +322,7 @@
put_reg(child, PT_SR, tmp);
wake_up_process(child);
ret = 0;
- goto out;
+ break;
}
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
@@ -328,12 +334,12 @@
tmp >>= 16;
if (put_user(tmp, (unsigned long *) data)) {
ret = -EFAULT;
- goto out;
+ break;
}
data += sizeof(long);
}
ret = 0;
- goto out;
+ break;
}
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
@@ -342,7 +348,7 @@
for (i = 0; i < 19; i++) {
if (get_user(tmp, (unsigned long *) data)) {
ret = -EFAULT;
- goto out;
+ break;
}
if (i == PT_SR) {
tmp &= SR_MASK;
@@ -353,7 +359,7 @@
data += sizeof(long);
}
ret = 0;
- goto out;
+ break;
}
case PTRACE_GETFPREGS: { /* Get the child FPU state. */
@@ -361,7 +367,7 @@
if (copy_to_user((void *)data, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
- goto out;
+ break;
}
case PTRACE_SETFPREGS: { /* Set the child FPU state. */
@@ -369,13 +375,15 @@
if (copy_from_user(&child->thread.fp, (void *)data,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
- goto out;
+ break;
}
default:
ret = -EIO;
- goto out;
+ break;
}
+out_tsk:
+ free_task_struct(child);
out:
unlock_kernel();
return ret;
@@ -383,10 +391,9 @@
asmlinkage void syscall_trace(void)
{
- lock_kernel();
if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
!= (PT_PTRACED|PT_TRACESYS))
- goto out;
+ return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
@@ -400,6 +407,4 @@
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
-out:
- unlock_kernel();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)