Re: [PATCH 1/2] unshare: Unsharing a thread does not require unsharing a vm

From: Oleg Nesterov
Date: Wed Aug 12 2015 - 13:51:11 EST


On 08/11, Eric W. Biederman wrote:
>
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1866,13 +1866,17 @@ static int check_unshare_flags(unsigned long unshare_flags)
> CLONE_NEWUSER|CLONE_NEWPID))
> return -EINVAL;
> /*
> - * Not implemented, but pretend it works if there is nothing to
> - * unshare. Note that unsharing CLONE_THREAD or CLONE_SIGHAND
> - * needs to unshare vm.
> + * Not implemented, but pretend it works if there is nothing
> + * to unshare. Note that unsharing the address space or the
> + * signal handlers also need to unshare the signal queues (aka
> + * CLONE_THREAD).
> */
> if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
> - /* FIXME: get_task_mm() increments ->mm_users */
> - if (atomic_read(&current->mm->mm_users) > 1)
> + if (!thread_group_empty(current))
> + return -EINVAL;
> + }
> + if (unshare_flags & CLONE_VM) {
> + if (!current_is_single_threaded())
> return -EINVAL;
> }

OK, but then you can remove "| CLONE_VM" from the previous check...


> @@ -1941,16 +1945,16 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
> if (unshare_flags & CLONE_NEWUSER)
> unshare_flags |= CLONE_THREAD | CLONE_FS;
> /*
> - * If unsharing a thread from a thread group, must also unshare vm.
> - */
> - if (unshare_flags & CLONE_THREAD)
> - unshare_flags |= CLONE_VM;

OK,

> /*
> + * If unsharing a signal handlers, must also unshare the signal queues.
> + */
> + if (unshare_flags & CLONE_SIGHAND)
> + unshare_flags |= CLONE_THREAD;

This looks unnecessary, check_unshare_flags() checks "THREAD | SIGHAND".
And to me the comment looks misleading although I won't argue.

And in fact this doesn't look exactly right, or I am totally confused.
Shouldn't we do

if (unshare_flags & CLONE_SIGHAND)
unshare_flags |= CLONE_VM;

? Or change check_unshare_flags()...

Otherwise suppose that a single threaded process does clone(VM | SIGHAND)
and (say) child does sys_unshare(SIGHAND). This will wrongly succeed afaics.

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/