| From e79f525e99b04390ca4d2366309545a836c03bf1 Mon Sep 17 00:00:00 2001 |
| From: Oleg Nesterov <oleg@redhat.com> |
| Date: Wed, 11 Sep 2013 14:19:38 -0700 |
| Subject: pidns: fix vfork() after unshare(CLONE_NEWPID) |
| |
| From: Oleg Nesterov <oleg@redhat.com> |
| |
| commit e79f525e99b04390ca4d2366309545a836c03bf1 upstream. |
| |
| Commit 8382fcac1b81 ("pidns: Outlaw thread creation after |
| unshare(CLONE_NEWPID)") nacks CLONE_VM if the forking process unshared |
| pid_ns, this obviously breaks vfork: |
| |
| int main(void) |
| { |
| assert(unshare(CLONE_NEWUSER | CLONE_NEWPID) == 0); |
| assert(vfork() >= 0); |
| _exit(0); |
| return 0; |
| } |
| |
| fails without this patch. |
| |
| Change this check to use CLONE_SIGHAND instead. This also forbids |
| CLONE_THREAD automatically, and this is what the comment implies. |
| |
| We could probably even drop CLONE_SIGHAND and use CLONE_THREAD, but it |
| would be safer to not do this. The current check denies CLONE_SIGHAND |
| implicitely and there is no reason to change this. |
| |
| Eric said "CLONE_SIGHAND is fine. CLONE_THREAD would be even better. |
| Having shared signal handling between two different pid namespaces is |
| the case that we are fundamentally guarding against." |
| |
| Signed-off-by: Oleg Nesterov <oleg@redhat.com> |
| Reported-by: Colin Walters <walters@redhat.com> |
| Acked-by: Andy Lutomirski <luto@amacapital.net> |
| Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| kernel/fork.c | 7 ++++--- |
| 1 file changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/kernel/fork.c |
| +++ b/kernel/fork.c |
| @@ -1171,10 +1171,11 @@ static struct task_struct *copy_process( |
| return ERR_PTR(-EINVAL); |
| |
| /* |
| - * If the new process will be in a different pid namespace |
| - * don't allow the creation of threads. |
| + * 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 ((clone_flags & (CLONE_VM|CLONE_NEWPID)) && |
| + if ((clone_flags & (CLONE_SIGHAND | CLONE_NEWPID)) && |
| (task_active_pid_ns(current) != current->nsproxy->pid_ns)) |
| return ERR_PTR(-EINVAL); |
| |