Currently this check for CLONE_NEWIPC with CLONE_SYSVSEM is done inside
copy_namespaces, resulting in a handful of error paths being executed if
these flags were used together. So, move this check to the beginning of
copy_process, exiting earlier if the condition is true.

This move is safe because copy_namespaces is called just from
copy_process function.

Signed-off-by: Marcos Paulo de Souza <marcos.souza....@gmail.com>
---
 kernel/fork.c    | 11 +++++++++++
 kernel/nsproxy.c | 11 -----------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index 2113e252cb9d..691f9ba135fc 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1600,6 +1600,17 @@ static __latent_entropy struct task_struct *copy_process(
                return ERR_PTR(-EINVAL);
 
        /*
+        * 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 ((clone_flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) ==
+               (CLONE_NEWIPC | CLONE_SYSVSEM))
+               return ERR_PTR(-EINVAL);
+
+       /*
         * Thread groups must share signals as well, and detached threads
         * can only be started up within the thread group.
         */
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index f6c5d330059a..30882727dff5 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -151,17 +151,6 @@ int copy_namespaces(unsigned long flags, struct 
task_struct *tsk)
        if (!ns_capable(user_ns, CAP_SYS_ADMIN))
                return -EPERM;
 
-       /*
-        * 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 | CLONE_SYSVSEM)) ==
-               (CLONE_NEWIPC | CLONE_SYSVSEM)) 
-               return -EINVAL;
-
        new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs);
        if (IS_ERR(new_ns))
                return  PTR_ERR(new_ns);
-- 
2.13.6

Reply via email to