edd: add default mode CONFIG_EDD_OFF=n, override with edd={on,off}
[linux-2.6.git] / kernel / nsproxy.c
index c8ef7c2..adc7851 100644 (file)
@@ -21,6 +21,7 @@
 #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;
 
@@ -129,7 +130,8 @@ 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_NEWNET)))
+       if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
+                               CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET)))
                return 0;
 
        if (!capable(CAP_SYS_ADMIN)) {
@@ -137,6 +139,18 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
                goto out;
        }
 
+       /*
+        * 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;
+       }
+
        new_ns = create_new_namespaces(flags, tsk, tsk->fs);
        if (IS_ERR(new_ns)) {
                err = PTR_ERR(new_ns);