]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] clone-fix-2.5.34-A0, BK-curr
authorIngo Molnar <mingo@elte.hu>
Sun, 15 Sep 2002 04:20:35 +0000 (21:20 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 15 Sep 2002 04:20:35 +0000 (21:20 -0700)
This fixes a clone-flags bug noticed by Roland McGrath.  The current
CLONE_DETACHED & CLONE_THREAD forcing code did things in the wrong
order, which makes it possible to force an oops the following way:

        main () { syscall(120, 0x00400000); }

instead of changing the order of CLONE_SIGHAND and CLONE_THREAD flag
forcing (which would fix the bug), the proper approach is to fail with
-EINVAL if invalid combinations of clone flags are detected.  This
change does not affect existing applications.

kernel/fork.c

index dec0136c59f1fe0bd6fcb561d16cae9387771fb2..1d2dc3d5b35106482933c05de8d8788ff337b3c1 100644 (file)
@@ -672,16 +672,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                return ERR_PTR(-EINVAL);
 
        /*
-        * Thread groups must share signals as well:
+        * Thread groups must share signals as well, and detached threads
+        * can only be started up within the thread group.
         */
-       if (clone_flags & CLONE_THREAD)
-               clone_flags |= CLONE_SIGHAND;
-       /*
-        * Detached threads can only be started up within the thread
-        * group.
-        */
-       if (clone_flags & CLONE_DETACHED)
-               clone_flags |= CLONE_THREAD;
+       if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND))
+               return ERR_PTR(-EINVAL);
+       if ((clone_flags & CLONE_DETACHED) && !(clone_flags & CLONE_THREAD))
+               return ERR_PTR(-EINVAL);
 
        retval = security_ops->task_create(clone_flags);
        if (retval)