trace: stop all recording to ring buffer on ftrace_dump
[safe/jmp/linux-2.6] / kernel / nsproxy.c
index 79f871b..63598dc 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/nsproxy.h>
 #include <linux/init_task.h>
 #include <linux/mnt_namespace.h>
 #include <linux/utsname.h>
 #include <linux/pid_namespace.h>
 #include <net/net_namespace.h>
+#include <linux/ipc_namespace.h>
 
 static struct kmem_cache *nsproxy_cachep;
 
@@ -80,12 +80,6 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
                goto out_pid;
        }
 
-       new_nsp->user_ns = copy_user_ns(flags, tsk->nsproxy->user_ns);
-       if (IS_ERR(new_nsp->user_ns)) {
-               err = PTR_ERR(new_nsp->user_ns);
-               goto out_user;
-       }
-
        new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns);
        if (IS_ERR(new_nsp->net_ns)) {
                err = PTR_ERR(new_nsp->net_ns);
@@ -95,9 +89,6 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
        return new_nsp;
 
 out_net:
-       if (new_nsp->user_ns)
-               put_user_ns(new_nsp->user_ns);
-out_user:
        if (new_nsp->pid_ns)
                put_pid_ns(new_nsp->pid_ns);
 out_pid:
@@ -130,7 +121,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
        get_nsproxy(old_ns);
 
        if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
-                               CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET)))
+                               CLONE_NEWPID | CLONE_NEWNET)))
                return 0;
 
        if (!capable(CAP_SYS_ADMIN)) {
@@ -138,15 +129,21 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
                goto out;
        }
 
-       new_ns = create_new_namespaces(flags, tsk, tsk->fs);
-       if (IS_ERR(new_ns)) {
-               err = PTR_ERR(new_ns);
+       /*
+        * CLONE_NEWIPC must detach from the undolist: after switching
+        * to a new ipc namespace, the semaphore arrays from the old
+        * namespace are unreachable.  In clone parlance, CLONE_SYSVSEM
+        * means share undolist with parent, so we must forbid using
+        * it along with CLONE_NEWIPC.
+        */
+       if ((flags & CLONE_NEWIPC) && (flags & CLONE_SYSVSEM)) {
+               err = -EINVAL;
                goto out;
        }
 
-       err = ns_cgroup_clone(tsk);
-       if (err) {
-               put_nsproxy(new_ns);
+       new_ns = create_new_namespaces(flags, tsk, tsk->fs);
+       if (IS_ERR(new_ns)) {
+               err = PTR_ERR(new_ns);
                goto out;
        }
 
@@ -167,8 +164,6 @@ 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);
        put_net(ns->net_ns);
        kmem_cache_free(nsproxy_cachep, ns);
 }
@@ -183,7 +178,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
        int err = 0;
 
        if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
-                              CLONE_NEWUSER | CLONE_NEWNET)))
+                              CLONE_NEWNET)))
                return 0;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -196,7 +191,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
                goto out;
        }
 
-       err = ns_cgroup_clone(current);
+       err = ns_cgroup_clone(current, task_pid(current));
        if (err)
                put_nsproxy(*new_nsp);