Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / um / kernel / ptrace.c
index e846eee..9a77fb3 100644 (file)
@@ -43,54 +43,10 @@ void ptrace_disable(struct task_struct *child)
 extern int peek_user(struct task_struct * child, long addr, long data);
 extern int poke_user(struct task_struct * child, long addr, long data);
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int i, ret;
-
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-       if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT))
-               goto out_tsk;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-#ifdef SUBACH_PTRACE_SPECIAL
-        SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
+       unsigned long __user *p = (void __user *)(unsigned long)data;
 
        switch (request) {
                /* when I and D space are separate, these will need to be fixed. */
@@ -103,7 +59,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
                if (copied != sizeof(tmp))
                        break;
-               ret = put_user(tmp, (unsigned long __user *) data);
+               ret = put_user(tmp, p);
                break;
        }
 
@@ -181,15 +137,13 @@ long sys_ptrace(long request, long pid, long addr, long data)
 
 #ifdef PTRACE_GETREGS
        case PTRACE_GETREGS: { /* Get all gp regs from the child. */
-               if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 
-                              MAX_REG_OFFSET)) {
+               if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
                        ret = -EIO;
                        break;
                }
                for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
-                       __put_user(getreg(child, i),
-                                  (unsigned long __user *) data);
-                       data += sizeof(long);
+                       __put_user(getreg(child, i), p);
+                       p++;
                }
                ret = 0;
                break;
@@ -198,15 +152,14 @@ long sys_ptrace(long request, long pid, long addr, long data)
 #ifdef PTRACE_SETREGS
        case PTRACE_SETREGS: { /* Set all gp regs in the child. */
                unsigned long tmp = 0;
-               if (!access_ok(VERIFY_READ, (unsigned *)data, 
-                              MAX_REG_OFFSET)) {
+               if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
                        ret = -EIO;
                        break;
                }
                for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
-                       __get_user(tmp, (unsigned long __user *) data);
+                       __get_user(tmp, p);
                        putreg(child, i, tmp);
-                       data += sizeof(long);
+                       p++;
                }
                ret = 0;
                break;
@@ -232,14 +185,23 @@ long sys_ptrace(long request, long pid, long addr, long data)
                ret = set_fpxregs(data, child);
                break;
 #endif
+       case PTRACE_GET_THREAD_AREA:
+               ret = ptrace_get_thread_area(child, addr,
+                                            (struct user_desc __user *) data);
+               break;
+
+       case PTRACE_SET_THREAD_AREA:
+               ret = ptrace_set_thread_area(child, addr,
+                                            (struct user_desc __user *) data);
+               break;
+
        case PTRACE_FAULTINFO: {
-                /* Take the info from thread->arch->faultinfo,
-                 * but transfer max. sizeof(struct ptrace_faultinfo).
-                 * On i386, ptrace_faultinfo is smaller!
-                 */
-                ret = copy_to_user((unsigned long __user *) data,
-                                   &child->thread.arch.faultinfo,
-                                   sizeof(struct ptrace_faultinfo));
+               /* Take the info from thread->arch->faultinfo,
+                * but transfer max. sizeof(struct ptrace_faultinfo).
+                * On i386, ptrace_faultinfo is smaller!
+                */
+               ret = copy_to_user(p, &child->thread.arch.faultinfo,
+                                  sizeof(struct ptrace_faultinfo));
                if(ret)
                        break;
                break;
@@ -249,8 +211,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
        case PTRACE_LDT: {
                struct ptrace_ldt ldt;
 
-               if(copy_from_user(&ldt, (unsigned long __user *) data,
-                                 sizeof(ldt))){
+               if(copy_from_user(&ldt, p, sizeof(ldt))){
                        ret = -EIO;
                        break;
                }
@@ -284,10 +245,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
- out_tsk:
-       put_task_struct(child);
- out:
-       unlock_kernel();
+
        return ret;
 }
 
@@ -317,15 +275,13 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
 
        if (unlikely(current->audit_context)) {
                if (!entryexit)
-                       audit_syscall_entry(current,
-                                            HOST_AUDIT_ARCH,
+                       audit_syscall_entry(HOST_AUDIT_ARCH,
                                            UPT_SYSCALL_NR(regs),
                                            UPT_SYSCALL_ARG1(regs),
                                            UPT_SYSCALL_ARG2(regs),
                                            UPT_SYSCALL_ARG3(regs),
                                            UPT_SYSCALL_ARG4(regs));
-               else audit_syscall_exit(current,
-                                        AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
+               else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
                                         UPT_SYSCALL_RET(regs));
        }