patch-2.4.3 linux/arch/sparc/kernel/ptrace.c
Next file: linux/arch/sparc/kernel/sys_sparc.c
Previous file: linux/arch/sparc/defconfig
Back to the patch index
Back to the overall index
- Lines: 266
- Date:
Sun Mar 25 18:14:21 2001
- Orig file:
v2.4.2/linux/arch/sparc/kernel/ptrace.c
- Orig date:
Wed Feb 21 18:20:15 2001
diff -u --recursive --new-file v2.4.2/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c
@@ -305,7 +305,13 @@
goto out;
}
#endif
- if(!(child = find_task_by_pid(pid))) {
+ 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);
goto out;
}
@@ -319,7 +325,7 @@
* You'll never be able to kill the process. ;-)
*/
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
if((!child->dumpable ||
(current->uid != child->euid) ||
@@ -330,12 +336,12 @@
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
@@ -347,21 +353,21 @@
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
if (!(child->ptrace & PT_PTRACED)) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
if(child->state != TASK_STOPPED) {
if(request != PTRACE_KILL) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
}
if(child->p_pptr != current) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
switch(request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -373,16 +379,16 @@
pt_os_succ_return(regs, tmp, (long *)data);
else
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
case PTRACE_PEEKUSR:
read_sunos_user(regs, addr, child, (long *) data);
- goto out;
+ goto out_tsk;
case PTRACE_POKEUSR:
write_sunos_user(regs, addr, child);
- goto out;
+ goto out_tsk;
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: {
@@ -391,7 +397,7 @@
pt_succ_return(regs, 0);
else
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETREGS: {
@@ -402,7 +408,7 @@
rval = verify_area(VERIFY_WRITE, pregs, sizeof(struct pt_regs));
if(rval) {
pt_error_return(regs, -rval);
- goto out;
+ goto out_tsk;
}
__put_user(cregs->psr, (&pregs->psr));
__put_user(cregs->pc, (&pregs->pc));
@@ -414,7 +420,7 @@
#ifdef DEBUG_PTRACE
printk ("PC=%x nPC=%x o7=%x\n", cregs->pc, cregs->npc, cregs->u_regs [15]);
#endif
- goto out;
+ goto out_tsk;
}
case PTRACE_SETREGS: {
@@ -429,7 +435,7 @@
i = verify_area(VERIFY_READ, pregs, sizeof(struct pt_regs));
if(i) {
pt_error_return(regs, -i);
- goto out;
+ goto out_tsk;
}
__get_user(psr, (&pregs->psr));
__get_user(pc, (&pregs->pc));
@@ -446,7 +452,7 @@
for(i = 1; i < 16; i++)
__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]));
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETFPREGS: {
@@ -466,7 +472,7 @@
i = verify_area(VERIFY_WRITE, fps, sizeof(struct fps));
if(i) {
pt_error_return(regs, -i);
- goto out;
+ goto out_tsk;
}
for(i = 0; i < 32; i++)
__put_user(child->thread.float_regs[i], (&fps->regs[i]));
@@ -480,7 +486,7 @@
__put_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETFPREGS: {
@@ -500,7 +506,7 @@
i = verify_area(VERIFY_READ, fps, sizeof(struct fps));
if(i) {
pt_error_return(regs, -i);
- goto out;
+ goto out_tsk;
}
copy_from_user(&child->thread.float_regs[0], &fps->regs[0], (32 * sizeof(unsigned long)));
__get_user(child->thread.fsr, (&fps->fsr));
@@ -511,7 +517,7 @@
__get_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_READTEXT:
@@ -520,13 +526,13 @@
if (res == data) {
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* Partial read is an IO failure */
if (res >= 0)
res = -EIO;
pt_error_return(regs, -res);
- goto out;
+ goto out_tsk;
}
case PTRACE_WRITETEXT:
@@ -535,13 +541,13 @@
if (res == data) {
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* Partial write is an IO failure */
if (res >= 0)
res = -EIO;
pt_error_return(regs, -res);
- goto out;
+ goto out_tsk;
}
case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
@@ -550,12 +556,12 @@
case PTRACE_CONT: { /* restart after signal. */
if ((unsigned long) data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
if (addr != 1) {
if (addr & 3) {
pt_error_return(regs, EINVAL);
- goto out;
+ goto out_tsk;
}
#ifdef DEBUG_PTRACE
printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc);
@@ -580,7 +586,7 @@
#endif
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/*
@@ -591,19 +597,19 @@
case PTRACE_KILL: {
if (child->state == TASK_ZOMBIE) { /* already dead */
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
wake_up_process(child);
child->exit_code = SIGKILL;
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SUNDETACH: { /* detach a process that was attached. */
unsigned long flags;
if ((unsigned long) data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process(child);
@@ -614,15 +620,18 @@
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* PTRACE_DUMPCORE unsupported... */
default:
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
+out_tsk:
+ if (child)
+ free_task_struct(child);
out:
unlock_kernel();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)