Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40a0d32d authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds
Browse files

fork: unify and tighten up CLONE_NEWUSER/CLONE_NEWPID checks



do_fork() denies CLONE_THREAD | CLONE_PARENT if NEWUSER | NEWPID.

Then later copy_process() denies CLONE_SIGHAND if the new process will
be in a different pid namespace (task_active_pid_ns() doesn't match
current->nsproxy->pid_ns).

This looks confusing and inconsistent.  CLONE_NEWPID is very similar to
the case when ->pid_ns was already unshared, we want the same
restrictions so copy_process() should also nack CLONE_PARENT.

And it would be better to deny CLONE_NEWUSER && CLONE_SIGHAND as well
just for consistency.

Kill the "CLONE_NEWUSER | CLONE_NEWPID" check in do_fork() and change
copy_process() to do the same check along with ->pid_ns check we already
have.

Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Acked-by: default avatarAndy Lutomirski <luto@amacapital.net>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Colin Walters <walters@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5167246a
Loading
Loading
Loading
Loading
+9 −15
Original line number Diff line number Diff line
@@ -1173,13 +1173,16 @@ static struct task_struct *copy_process(unsigned long clone_flags,
		return ERR_PTR(-EINVAL);

	/*
	 * If the new process will be in a different pid namespace don't
	 * allow it to share a thread group or signal handlers with the
	 * forking task.
	 * If the new process will be in a different pid or user namespace
	 * do not allow it to share a thread group or signal handlers or
	 * parent with the forking task.
	 */
	if ((clone_flags & CLONE_SIGHAND) && (task_active_pid_ns(current) !=
	if (clone_flags & (CLONE_SIGHAND | CLONE_PARENT)) {
		if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) ||
		    (task_active_pid_ns(current) !=
				current->nsproxy->pid_ns_for_children))
			return ERR_PTR(-EINVAL);
	}

	retval = security_task_create(clone_flags);
	if (retval)
@@ -1575,15 +1578,6 @@ long do_fork(unsigned long clone_flags,
	int trace = 0;
	long nr;

	/*
	 * Do some preliminary argument and permissions checking before we
	 * actually start allocating stuff
	 */
	if (clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) {
		if (clone_flags & (CLONE_THREAD|CLONE_PARENT))
			return -EINVAL;
	}

	/*
	 * Determine whether and which event to report to ptracer.  When
	 * called from kernel_thread or CLONE_UNTRACED is explicitly