diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 21:05:59 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 21:05:59 +0000 |
commit | ba2dacab305c598cd4c34a604f8e276bf5bab5ff (patch) | |
tree | 78670a0139bf4d5ace617b29b7eba82bbc74d602 /arch/mips64/kernel/ptrace.c | |
parent | b77bf69998121e689c5e86cc5630d39a0a9ee6ca (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.c | 76 |
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; |