vserver 1.9.5.x5
[linux-2.6.git] / arch / sparc64 / kernel / ptrace.c
index d935eb6..1e091dd 100644 (file)
@@ -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