}
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, addr))
- return pt_error_return(regs, EFAULT);
+ if (put_user(value, addr)) {
+ pt_error_return(regs, EFAULT);
+ return;
+ }
regs->u_regs[UREG_I0] = 0;
regs->psr &= ~PSR_C;
regs->pc = regs->npc;
}
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);
/* 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;
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)) {
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:
}
case PTRACE_GETREGS: {
- struct pt_regs *pregs = (struct pt_regs *) addr;
+ struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
struct pt_regs *cregs = child->thread.kregs;
int rval;
}
case PTRACE_SETREGS: {
- struct pt_regs *pregs = (struct pt_regs *) addr;
+ struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
struct pt_regs *cregs = child->thread.kregs;
unsigned long psr, pc, npc, y;
int i;
unsigned long *insnaddr;
unsigned long insn;
} fpq[16];
- } *fps = (struct fps *) addr;
+ };
+ struct fps __user *fps = (struct fps __user *) addr;
int i;
i = verify_area(VERIFY_WRITE, fps, sizeof(struct fps));
unsigned long *insnaddr;
unsigned long insn;
} fpq[16];
- } *fps = (struct fps *) addr;
+ };
+ struct fps __user *fps = (struct fps __user *) addr;
int i;
i = verify_area(VERIFY_READ, fps, sizeof(struct fps));
case PTRACE_READTEXT:
case PTRACE_READDATA: {
- int res = ptrace_readdata(child, addr, (void *) addr2, data);
+ int res = ptrace_readdata(child, addr,
+ (void __user *) addr2, data);
if (res == data) {
pt_succ_return(regs, 0);
case PTRACE_WRITETEXT:
case PTRACE_WRITEDATA: {
- int res = ptrace_writedata(child, (void *) addr2, addr, data);
+ int res = ptrace_writedata(child, (void __user *) addr2,
+ addr, data);
if (res == data) {
pt_succ_return(regs, 0);
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);
* 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;
}
return;
if (!(current->ptrace & PT_PTRACED))
return;
- current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0);
- current->state = TASK_STOPPED;
current->thread.flags ^= MAGIC_CONSTANT;
- 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
* for normal use. strace only continues with a signal if the