Merge commit '12890d0f61fc' into arch-mips
[firefly-linux-kernel-4.4.55.git] / kernel / ptrace.c
index 1f5e55dda955544ca4a3f1f944e967f6b561bea2..612a5612685119938df3acd9145135b489bff1d6 100644 (file)
@@ -139,7 +139,7 @@ void __ptrace_unlink(struct task_struct *child)
  * RETURNS:
  * 0 on success, -ESRCH if %child is not ready.
  */
-int ptrace_check_attach(struct task_struct *child, bool ignore_state)
+static int ptrace_check_attach(struct task_struct *child, bool ignore_state)
 {
        int ret = -ESRCH;
 
@@ -215,8 +215,12 @@ ok:
        smp_rmb();
        if (task->mm)
                dumpable = get_dumpable(task->mm);
-       if (!dumpable  && !ptrace_has_cap(task_user_ns(task), mode))
+       rcu_read_lock();
+       if (!dumpable && !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
+               rcu_read_unlock();
                return -EPERM;
+       }
+       rcu_read_unlock();
 
        return security_ptrace_access_check(task, mode);
 }
@@ -280,8 +284,10 @@ static int ptrace_attach(struct task_struct *task, long request,
 
        if (seize)
                flags |= PT_SEIZED;
-       if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))
+       rcu_read_lock();
+       if (ns_capable(__task_cred(task)->user_ns, CAP_SYS_PTRACE))
                flags |= PT_PTRACE_CAP;
+       rcu_read_unlock();
        task->ptrace = flags;
 
        __ptrace_link(task, current);
@@ -457,6 +463,9 @@ void exit_ptrace(struct task_struct *tracer)
                return;
 
        list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
+               if (unlikely(p->ptrace & PT_EXITKILL))
+                       send_sig_info(SIGKILL, SEND_SIG_FORCED, p);
+
                if (__ptrace_detach(tracer, p))
                        list_add(&p->ptrace_entry, &ptrace_dead);
        }