HWPOISON: Add PR_MCE_KILL prctl to control early kill behaviour per process
[safe/jmp/linux-2.6] / kernel / ptrace.c
index 38fdfea..307c285 100644 (file)
@@ -152,7 +152,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
        if (!dumpable && !capable(CAP_SYS_PTRACE))
                return -EPERM;
 
-       return security_ptrace_may_access(task, mode);
+       return security_ptrace_access_check(task, mode);
 }
 
 bool ptrace_may_access(struct task_struct *task, unsigned int mode)
@@ -181,8 +181,8 @@ int ptrace_attach(struct task_struct *task)
         * interference; SUID, SGID and LSM creds get determined differently
         * under ptrace.
         */
-       retval = mutex_lock_interruptible(&task->cred_guard_mutex);
-       if (retval < 0)
+       retval = -ERESTARTNOINTR;
+       if (mutex_lock_interruptible(&task->cred_guard_mutex))
                goto out;
 
        task_lock(task);
@@ -424,37 +424,33 @@ static int ptrace_setoptions(struct task_struct *child, long data)
 
 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
 {
+       unsigned long flags;
        int error = -ESRCH;
 
-       read_lock(&tasklist_lock);
-       if (likely(child->sighand != NULL)) {
+       if (lock_task_sighand(child, &flags)) {
                error = -EINVAL;
-               spin_lock_irq(&child->sighand->siglock);
                if (likely(child->last_siginfo != NULL)) {
                        *info = *child->last_siginfo;
                        error = 0;
                }
-               spin_unlock_irq(&child->sighand->siglock);
+               unlock_task_sighand(child, &flags);
        }
-       read_unlock(&tasklist_lock);
        return error;
 }
 
 static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info)
 {
+       unsigned long flags;
        int error = -ESRCH;
 
-       read_lock(&tasklist_lock);
-       if (likely(child->sighand != NULL)) {
+       if (lock_task_sighand(child, &flags)) {
                error = -EINVAL;
-               spin_lock_irq(&child->sighand->siglock);
                if (likely(child->last_siginfo != NULL)) {
                        *child->last_siginfo = *info;
                        error = 0;
                }
-               spin_unlock_irq(&child->sighand->siglock);
+               unlock_task_sighand(child, &flags);
        }
-       read_unlock(&tasklist_lock);
        return error;
 }
 
@@ -581,26 +577,16 @@ int ptrace_request(struct task_struct *child, long request,
        return ret;
 }
 
-/**
- * ptrace_get_task_struct  --  grab a task struct reference for ptrace
- * @pid:       process id to grab a task_struct reference of
- *
- * This function is a helper for ptrace implementations.  It checks
- * permissions and then grabs a task struct for use of the actual
- * ptrace implementation.
- *
- * Returns the task_struct for @pid or an ERR_PTR() on failure.
- */
-struct task_struct *ptrace_get_task_struct(pid_t pid)
+static struct task_struct *ptrace_get_task_struct(pid_t pid)
 {
        struct task_struct *child;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        child = find_task_by_vpid(pid);
        if (child)
                get_task_struct(child);
+       rcu_read_unlock();
 
-       read_unlock(&tasklist_lock);
        if (!child)
                return ERR_PTR(-ESRCH);
        return child;