X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc%2Fkernel%2Fptrace.c;h=11cf8619dd8e9a5c86cccdac7fb31a9e79d395f6;hb=refs%2Fheads%2Fvserver;hp=d39739182456f9f60fcf858d00f68d5a852da41a;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index d39739182..11cf8619d 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -48,9 +50,9 @@ static inline void pt_succ_return(struct pt_regs *regs, unsigned long value) } static void -pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr) +pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long __user *addr) { - if (put_user(value, (long __user *) addr)) { + if (put_user(value, addr)) { pt_error_return(regs, EFAULT); return; } @@ -61,7 +63,7 @@ pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr) } static void -pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr) +pt_os_succ_return (struct pt_regs *regs, unsigned long val, long __user *addr) { if (current->personality == PER_SUNOS) pt_succ_return (regs, val); @@ -71,10 +73,10 @@ pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr) /* Fuck me gently with a chainsaw... */ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, - struct task_struct *tsk, long *addr) + struct task_struct *tsk, long __user *addr) { struct pt_regs *cregs = tsk->thread.kregs; - struct thread_info *t = tsk->thread_info; + struct thread_info *t = task_thread_info(tsk); int v; if(offset >= 1024) @@ -169,7 +171,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset, struct task_struct *tsk) { struct pt_regs *cregs = tsk->thread.kregs; - struct thread_info *t = tsk->thread_info; + struct thread_info *t = task_thread_info(tsk); unsigned long value = regs->u_regs[UREG_I3]; if(offset >= 1024) @@ -285,43 +287,23 @@ asmlinkage void do_ptrace(struct pt_regs *regs) s, (int) request, (int) pid, addr, data, addr2); } #endif - if(request == PTRACE_TRACEME) { - int ret; - /* are we already being traced? */ - if (current->ptrace & PT_PTRACED) { - pt_error_return(regs, EPERM); - goto out; - } - ret = security_ptrace(current->parent, current); - if (ret) { + if (request == PTRACE_TRACEME) { + ret = ptrace_traceme(); + if (ret < 0) pt_error_return(regs, -ret); - goto out; - } - - /* set the ptrace bit in the process flags. */ - current->ptrace |= PT_PTRACED; - pt_succ_return(regs, 0); - goto out; - } -#ifndef ALLOW_INIT_TRACING - if(pid == 1) { - /* Can't dork with init. */ - pt_error_return(regs, EPERM); + else + pt_succ_return(regs, 0); goto out; } -#endif - 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); + child = ptrace_get_task_struct(pid); + if (IS_ERR(child)) { + ret = PTR_ERR(child); + pt_error_return(regs, -ret); goto out; } - if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) { pt_error_return(regs, ESRCH); goto out_tsk; } @@ -349,14 +331,14 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (access_process_vm(child, addr, &tmp, sizeof(tmp), 0) == sizeof(tmp)) - pt_os_succ_return(regs, tmp, (long *)data); + pt_os_succ_return(regs, tmp, (long __user *)data); else pt_error_return(regs, EIO); goto out_tsk; } case PTRACE_PEEKUSR: - read_sunos_user(regs, addr, child, (long *) data); + read_sunos_user(regs, addr, child, (long __user *) data); goto out_tsk; case PTRACE_POKEUSR: @@ -378,8 +360,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) struct pt_regs *cregs = child->thread.kregs; int rval; - rval = verify_area(VERIFY_WRITE, pregs, sizeof(struct pt_regs)); - if(rval) { + if (!access_ok(VERIFY_WRITE, pregs, sizeof(struct pt_regs))) { + rval = -EFAULT; pt_error_return(regs, -rval); goto out_tsk; } @@ -405,9 +387,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) /* Must be careful, tracing process can only set certain * bits in the psr. */ - i = verify_area(VERIFY_READ, pregs, sizeof(struct pt_regs)); - if(i) { - pt_error_return(regs, -i); + if (!access_ok(VERIFY_READ, pregs, sizeof(struct pt_regs))) { + pt_error_return(regs, EFAULT); goto out_tsk; } __get_user(psr, (&pregs->psr)); @@ -417,7 +398,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) psr &= PSR_ICC; cregs->psr &= ~PSR_ICC; cregs->psr |= psr; - if(!((pc | npc) & 3)) { + if (!((pc | npc) & 3)) { cregs->pc = pc; cregs->npc =npc; } @@ -443,8 +424,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) struct fps __user *fps = (struct fps __user *) addr; int i; - i = verify_area(VERIFY_WRITE, fps, sizeof(struct fps)); - if(i) { + if (!access_ok(VERIFY_WRITE, fps, sizeof(struct fps))) { + i = -EFAULT; pt_error_return(regs, -i); goto out_tsk; } @@ -478,8 +459,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) struct fps __user *fps = (struct fps __user *) addr; int i; - i = verify_area(VERIFY_READ, fps, sizeof(struct fps)); - if(i) { + if (!access_ok(VERIFY_READ, fps, sizeof(struct fps))) { + i = -EFAULT; pt_error_return(regs, -i); goto out_tsk; } @@ -531,22 +512,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) addr = 1; case PTRACE_CONT: { /* restart after signal. */ - if (data > _NSIG) { + if (!valid_signal(data)) { pt_error_return(regs, EIO); goto out_tsk; } - if (addr != 1) { - if (addr & 3) { - pt_error_return(regs, EINVAL); - goto out_tsk; - } -#ifdef DEBUG_PTRACE - printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc); - printk ("Continuing with %08lx %08lx\n", addr, addr+4); -#endif - child->thread.kregs->pc = addr; - child->thread.kregs->npc = addr + 4; - } if (request == PTRACE_SYSCALL) set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); @@ -571,7 +540,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) * exit. */ case PTRACE_KILL: { - if (child->state == TASK_ZOMBIE) { /* already dead */ + if (child->exit_state == EXIT_ZOMBIE) { /* already dead */ pt_succ_return(regs, 0); goto out_tsk; }