user namespace: add the framework
[linux-block.git] / kernel / nsproxy.c
index 1bc4b55241a8c720e16a5ed12efd108875229dcc..895e3a3f20442e9420464b00889ec16583fea313 100644 (file)
@@ -79,8 +79,15 @@ static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
        if (IS_ERR(new_nsp->pid_ns))
                goto out_pid;
 
+       new_nsp->user_ns = copy_user_ns(flags, tsk->nsproxy->user_ns);
+       if (IS_ERR(new_nsp->user_ns))
+               goto out_user;
+
        return new_nsp;
 
+out_user:
+       if (new_nsp->pid_ns)
+               put_pid_ns(new_nsp->pid_ns);
 out_pid:
        if (new_nsp->ipc_ns)
                put_ipc_ns(new_nsp->ipc_ns);
@@ -140,43 +147,29 @@ void free_nsproxy(struct nsproxy *ns)
                put_ipc_ns(ns->ipc_ns);
        if (ns->pid_ns)
                put_pid_ns(ns->pid_ns);
+       if (ns->user_ns)
+               put_user_ns(ns->user_ns);
        kfree(ns);
 }
 
 /*
  * Called from unshare. Unshare all the namespaces part of nsproxy.
- * On sucess, returns the new nsproxy and a reference to old nsproxy
- * to make sure it stays around.
+ * On success, returns the new nsproxy.
  */
 int unshare_nsproxy_namespaces(unsigned long unshare_flags,
                struct nsproxy **new_nsp, struct fs_struct *new_fs)
 {
-       struct nsproxy *old_ns = current->nsproxy;
        int err = 0;
 
        if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
                return 0;
 
-#ifndef CONFIG_IPC_NS
-       if (unshare_flags & CLONE_NEWIPC)
-               return -EINVAL;
-#endif
-
-#ifndef CONFIG_UTS_NS
-       if (unshare_flags & CLONE_NEWUTS)
-               return -EINVAL;
-#endif
-
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       get_nsproxy(old_ns);
-
        *new_nsp = create_new_namespaces(unshare_flags, current,
                                new_fs ? new_fs : current->fs);
-       if (IS_ERR(*new_nsp)) {
+       if (IS_ERR(*new_nsp))
                err = PTR_ERR(*new_nsp);
-               put_nsproxy(old_ns);
-       }
        return err;
 }