Initialise scatter/gather list in sg driver
[safe/jmp/linux-2.6] / kernel / ptrace.c
index 1653d35..7c76f2f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/security.h>
 #include <linux/signal.h>
 #include <linux/audit.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -142,7 +143,7 @@ static int may_attach(struct task_struct *task)
                return -EPERM;
        smp_rmb();
        if (task->mm)
-               dumpable = task->mm->dumpable;
+               dumpable = get_dumpable(task->mm);
        if (!dumpable && !capable(CAP_SYS_PTRACE))
                return -EPERM;
 
@@ -168,7 +169,7 @@ int ptrace_attach(struct task_struct *task)
        retval = -EPERM;
        if (task->pid <= 1)
                goto out;
-       if (task->tgid == current->tgid)
+       if (same_thread_group(task, current))
                goto out;
 
 repeat:
@@ -233,6 +234,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data)
 
        /* Architecture-specific hardware disable .. */
        ptrace_disable(child);
+       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 
        write_lock_irq(&tasklist_lock);
        /* protect against de_thread()->release_task() */
@@ -385,6 +387,9 @@ int ptrace_request(struct task_struct *child, long request,
        case PTRACE_SETSIGINFO:
                ret = ptrace_setsiginfo(child, (siginfo_t __user *) data);
                break;
+       case PTRACE_DETACH:      /* detach a process that was attached. */
+               ret = ptrace_detach(child, data);
+               break;
        default:
                break;
        }
@@ -439,7 +444,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
                return ERR_PTR(-EPERM);
 
        read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
+       child = find_task_by_vpid(pid);
        if (child)
                get_task_struct(child);
 
@@ -449,6 +454,10 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
        return child;
 }
 
+#ifndef arch_ptrace_attach
+#define arch_ptrace_attach(child)      do { } while (0)
+#endif
+
 #ifndef __ARCH_SYS_PTRACE
 asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
@@ -472,6 +481,12 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 
        if (request == PTRACE_ATTACH) {
                ret = ptrace_attach(child);
+               /*
+                * Some architectures need to do book-keeping after
+                * a ptrace attach.
+                */
+               if (!ret)
+                       arch_ptrace_attach(child);
                goto out_put_task_struct;
        }
 
@@ -501,3 +516,11 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
                return -EIO;
        return put_user(tmp, (unsigned long __user *)data);
 }
+
+int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
+{
+       int copied;
+
+       copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
+       return (copied == sizeof(data)) ? 0 : -EIO;
+}