*/
        struct task_struct __rcu *owner;
 #endif
+       struct user_namespace *user_ns;
 
        /* store ref to file /proc/<pid>/exe symlink points to */
        struct file __rcu *exe_file;
 
 #endif
 }
 
-static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
+static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
+       struct user_namespace *user_ns)
 {
        mm->mmap = NULL;
        mm->mm_rb = RB_ROOT;
        if (init_new_context(p, mm))
                goto fail_nocontext;
 
+       mm->user_ns = get_user_ns(user_ns);
        return mm;
 
 fail_nocontext:
                return NULL;
 
        memset(mm, 0, sizeof(*mm));
-       return mm_init(mm, current);
+       return mm_init(mm, current, current_user_ns());
 }
 
 /*
        destroy_context(mm);
        mmu_notifier_mm_destroy(mm);
        check_mm(mm);
+       put_user_ns(mm->user_ns);
        free_mm(mm);
 }
 EXPORT_SYMBOL_GPL(__mmdrop);
 
        memcpy(mm, oldmm, sizeof(*mm));
 
-       if (!mm_init(mm, tsk))
+       if (!mm_init(mm, tsk, mm->user_ns))
                goto fail_nomem;
 
        err = dup_mmap(mm, oldmm);
 
 static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 {
        const struct cred *cred = current_cred(), *tcred;
-       int dumpable = 0;
+       struct mm_struct *mm;
        kuid_t caller_uid;
        kgid_t caller_gid;
 
        return -EPERM;
 ok:
        rcu_read_unlock();
-       smp_rmb();
-       if (task->mm)
-               dumpable = get_dumpable(task->mm);
-       rcu_read_lock();
-       if (dumpable != SUID_DUMP_USER &&
-           !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
-               rcu_read_unlock();
-               return -EPERM;
-       }
-       rcu_read_unlock();
+       mm = task->mm;
+       if (mm &&
+           ((get_dumpable(mm) != SUID_DUMP_USER) &&
+            !ptrace_has_cap(mm->user_ns, mode)))
+           return -EPERM;
 
        return security_ptrace_access_check(task, mode);
 }
 
        task_lock(task);
        retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
+       if (!retval) {
+               struct mm_struct *mm = task->mm;
+               if (mm && ns_capable(mm->user_ns, CAP_SYS_PTRACE))
+                       flags |= PT_PTRACE_CAP;
+       }
        task_unlock(task);
        if (retval)
                goto unlock_creds;
 
        if (seize)
                flags |= PT_SEIZED;
-       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);
 
 #include <linux/cpumask.h>
 
 #include <linux/atomic.h>
+#include <linux/user_namespace.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 
        .mmap_sem       = __RWSEM_INITIALIZER(init_mm.mmap_sem),
        .page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
        .mmlist         = LIST_HEAD_INIT(init_mm.mmlist),
+       .user_ns        = &init_user_ns,
        INIT_MM_CONTEXT(init_mm)
 };