X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fptrace.c;h=1e091ddaba981e8dbc1463480db5e41de4e95746;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=d935eb602ce6882aff22616b4f489b5c08de6c0a;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index d935eb602..1e091ddab 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -50,14 +50,18 @@ static inline void pt_succ_return(struct pt_regs *regs, unsigned long value) } static inline 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, void __user *addr) { if (test_thread_flag(TIF_32BIT)) { - if (put_user(value, (unsigned int *)addr)) - return pt_error_return(regs, EFAULT); + if (put_user(value, (unsigned int __user *) addr)) { + pt_error_return(regs, EFAULT); + return; + } } else { - if (put_user(value, addr)) - return pt_error_return(regs, EFAULT); + if (put_user(value, (long __user *) addr)) { + pt_error_return(regs, EFAULT); + return; + } } regs->u_regs[UREG_I0] = 0; regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY); @@ -66,7 +70,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, void __user *addr) { if (current->personality == PER_SUNOS) pt_succ_return (regs, val); @@ -168,6 +172,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_error_return(regs, ESRCH); goto out; } + if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { + pt_error_return(regs, ESRCH); + goto out_tsk; + } if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { @@ -222,7 +230,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (res < 0) pt_error_return(regs, -res); else - pt_os_succ_return(regs, tmp64, (long *) data); + pt_os_succ_return(regs, tmp64, (void __user *) data); goto flush_and_out; } @@ -253,7 +261,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } case PTRACE_GETREGS: { - struct pt_regs32 *pregs = (struct pt_regs32 *) addr; + struct pt_regs32 __user *pregs = + (struct pt_regs32 __user *) addr; struct pt_regs *cregs = child->thread_info->kregs; int rval; @@ -277,7 +286,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } case PTRACE_GETREGS64: { - struct pt_regs *pregs = (struct pt_regs *) addr; + struct pt_regs __user *pregs = (struct pt_regs __user *) addr; struct pt_regs *cregs = child->thread_info->kregs; unsigned long tpc = cregs->tpc; int rval; @@ -304,7 +313,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } case PTRACE_SETREGS: { - struct pt_regs32 *pregs = (struct pt_regs32 *) addr; + struct pt_regs32 __user *pregs = + (struct pt_regs32 __user *) addr; struct pt_regs *cregs = child->thread_info->kregs; unsigned int psr, pc, npc, y; int i; @@ -337,7 +347,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } case PTRACE_SETREGS64: { - struct pt_regs *pregs = (struct pt_regs *) addr; + struct pt_regs __user *pregs = (struct pt_regs __user *) addr; struct pt_regs *cregs = child->thread_info->kregs; unsigned long tstate, tpc, tnpc, y; int i; @@ -385,7 +395,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int insnaddr; unsigned int insn; } fpq[16]; - } *fps = (struct fps *) addr; + }; + struct fps __user *fps = (struct fps __user *) addr; unsigned long *fpregs = child->thread_info->fpregs; if (copy_to_user(&fps->regs[0], fpregs, @@ -406,7 +417,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) struct fps { unsigned int regs[64]; unsigned long fsr; - } *fps = (struct fps *) addr; + }; + struct fps __user *fps = (struct fps __user *) addr; unsigned long *fpregs = child->thread_info->fpregs; if (copy_to_user(&fps->regs[0], fpregs, @@ -430,7 +442,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int insnaddr; unsigned int insn; } fpq[16]; - } *fps = (struct fps *) addr; + }; + struct fps __user *fps = (struct fps __user *) addr; unsigned long *fpregs = child->thread_info->fpregs; unsigned fsr; @@ -453,7 +466,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs) struct fps { unsigned int regs[64]; unsigned long fsr; - } *fps = (struct fps *) addr; + }; + struct fps __user *fps = (struct fps __user *) addr; unsigned long *fpregs = child->thread_info->fpregs; if (copy_from_user(fpregs, &fps->regs[0], @@ -472,7 +486,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_READTEXT: case PTRACE_READDATA: { int res = ptrace_readdata(child, addr, - (void *)addr2, data); + (char __user *)addr2, data); if (res == data) { pt_succ_return(regs, 0); goto flush_and_out; @@ -485,7 +499,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_WRITETEXT: case PTRACE_WRITEDATA: { - int res = ptrace_writedata(child, (void *) addr2, + int res = ptrace_writedata(child, (char __user *) addr2, addr, data); if (res == data) { pt_succ_return(regs, 0); @@ -549,7 +563,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; } @@ -617,11 +631,8 @@ asmlinkage void syscall_trace(void) return; if (!(current->ptrace & PT_PTRACED)) return; - current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0); - current->state = TASK_STOPPED; - notify_parent(current, SIGCHLD); - schedule(); + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); /* * this isn't the same as continuing with a signal, but it will do