|
@@ -1565,9 +1565,11 @@ long do_fork(unsigned long clone_flags,
|
|
|
* Do some preliminary argument and permissions checking before we
|
|
|
* actually start allocating stuff
|
|
|
*/
|
|
|
- if (clone_flags & CLONE_NEWUSER) {
|
|
|
- if (clone_flags & CLONE_THREAD)
|
|
|
+ if (clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) {
|
|
|
+ if (clone_flags & (CLONE_THREAD|CLONE_PARENT))
|
|
|
return -EINVAL;
|
|
|
+ }
|
|
|
+ if (clone_flags & CLONE_NEWUSER) {
|
|
|
/* hopefully this check will go away when userns support is
|
|
|
* complete
|
|
|
*/
|
|
@@ -1692,7 +1694,8 @@ static int check_unshare_flags(unsigned long unshare_flags)
|
|
|
{
|
|
|
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
|
|
|
CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
|
|
|
- CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET))
|
|
|
+ CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
|
|
|
+ CLONE_NEWPID))
|
|
|
return -EINVAL;
|
|
|
/*
|
|
|
* Not implemented, but pretend it works if there is nothing to
|
|
@@ -1763,15 +1766,30 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
|
|
|
int do_sysvsem = 0;
|
|
|
int err;
|
|
|
|
|
|
- err = check_unshare_flags(unshare_flags);
|
|
|
- if (err)
|
|
|
- goto bad_unshare_out;
|
|
|
-
|
|
|
+ /*
|
|
|
+ * If unsharing a pid namespace must also unshare the thread.
|
|
|
+ */
|
|
|
+ if (unshare_flags & CLONE_NEWPID)
|
|
|
+ unshare_flags |= CLONE_THREAD;
|
|
|
+ /*
|
|
|
+ * If unsharing a thread from a thread group, must also unshare vm.
|
|
|
+ */
|
|
|
+ if (unshare_flags & CLONE_THREAD)
|
|
|
+ unshare_flags |= CLONE_VM;
|
|
|
+ /*
|
|
|
+ * If unsharing vm, must also unshare signal handlers.
|
|
|
+ */
|
|
|
+ if (unshare_flags & CLONE_VM)
|
|
|
+ unshare_flags |= CLONE_SIGHAND;
|
|
|
/*
|
|
|
* If unsharing namespace, must also unshare filesystem information.
|
|
|
*/
|
|
|
if (unshare_flags & CLONE_NEWNS)
|
|
|
unshare_flags |= CLONE_FS;
|
|
|
+
|
|
|
+ err = check_unshare_flags(unshare_flags);
|
|
|
+ if (err)
|
|
|
+ goto bad_unshare_out;
|
|
|
/*
|
|
|
* CLONE_NEWIPC must also detach from the undolist: after switching
|
|
|
* to a new ipc namespace, the semaphore arrays from the old
|