From: Oleg Nesterov <oleg@redhat.com>
To: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>,
Andrew Morton <akpm@linux-foundation.org>,
Kees Cook <keescook@chromium.org>,
David Howells <dhowells@redhat.com>,
linux-kernel@vger.kernel.org,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>,
"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
Rik van Riel <riel@redhat.com>,
Vladimir Davydov <vdavydov@parallels.com>,
Ricky Zhou <rickyz@chromium.org>, Julien Tinnes <jln@google.com>
Subject: Re: [PATCH 1/2] unshare: Unsharing a thread does not require unsharing a vm
Date: Thu, 13 Aug 2015 14:55:50 +0200 [thread overview]
Message-ID: <20150813125550.GA13984@redhat.com> (raw)
In-Reply-To: <87614k73mo.fsf@x220.int.ebiederm.org>
Let me first say that CLONE_SIGHAND must die, I think ;) and perhaps
even sighand_struct... I am wondering if we can add something like
if ((clone_flags & (CLONE_THREAD | CLONE_SIGHAND)) == CLONE_SIGHAND)
pr_info("You are crazy, please report this to lkml\n");
into copy_process().
On 08/12, Eric W. Biederman wrote:
>
> Oleg Nesterov <oleg@redhat.com> writes:
>
> > On 08/11, Eric W. Biederman wrote:
> >> if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
> >> - /* FIXME: get_task_mm() increments ->mm_users */
> >> - if (atomic_read(¤t->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...
>
> As an optimization, but I don't think anything cares enough for the
> optimization to be worth the confusion.
current_is_single_threaded() checks task->signal->live at the start,
so there is no optimization. But I won't argue, this doesn't hurt.
> >> /*
> >> + * 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.
>
> I absolutely can not understand this code if we jump 5 steps ahead
> and optimize out the individual dependencies, and try for a flattened
> dependency tree instead. I can validate the individual dependencies
> from first principles.
>
> If we jump several steps ahead I can not validate the individual
> dependencies.
OK,
> > 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;
>
> Nope. The backward definitions of the flags in unshare has gotten you.
See below,
> CLONE_SIGHAND means that you want a struct sighand_struct with a count
> of 1.
This is (almost) true,
> Nothing about a sighand_struct with a count of 1 implies or
> requires mm_users == 1. clone can quite happily create those.
See
if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM))
in copy_process(). So if you have a shared sighand_struct, your ->mm
is also shared, current_is_single_threaded() will notice this.
> > Otherwise suppose that a single threaded process does clone(VM | SIGHAND)
> > and (say) child does sys_unshare(SIGHAND). This will wrongly succeed
> > afaics.
>
> Why would it be wrong to succeed in that case? struct sighand_struct
> has a count of 1.
How that? clone(VM | SIGHAND) will share ->sighand and increment its
count.
> unshare(CLONE_SIGHAND) requests a sighand_struct with
> a count of 1.
Exactly, that is why it is wrong to succeed.
> unshare(SIGHAND) needs to guarantee that when it returns sighand->count == 1.
> So unshare(SIGHAND) needs to test for sighand->count == 1.
Oh, I do not think we should check sighand->count. This can lead to
the same problem we have with the current current->mm->mm_users check.
Most probably today nobody increments sighand->count (I didn't even
try to verify). But this is possible, and I saw the code which did
this to pin ->sighand...
Oleg.
next prev parent reply other threads:[~2015-08-13 12:58 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-28 17:15 [PATCH] user_ns: use correct check for single-threadedness Kees Cook
2015-07-28 18:02 ` Rik van Riel
2015-07-28 18:17 ` Eric W. Biederman
2015-07-28 20:55 ` Ricky Zhou
2015-07-28 21:01 ` Kees Cook
2015-08-05 18:13 ` Eric W. Biederman
2015-08-05 19:40 ` Kees Cook
2015-07-28 21:35 ` Andrew Morton
2015-07-28 21:50 ` Kees Cook
2015-07-28 22:11 ` Kirill A. Shutemov
2015-08-05 11:38 ` Ingo Molnar
2015-08-05 11:53 ` Kirill A. Shutemov
2015-08-05 13:13 ` Ricky Zhou
2015-08-05 17:23 ` Oleg Nesterov
2015-08-05 18:00 ` Eric W. Biederman
2015-08-05 18:52 ` Eric W. Biederman
2015-08-06 13:06 ` Oleg Nesterov
2015-08-06 13:44 ` Oleg Nesterov
2015-08-12 1:17 ` Eric W. Biederman
2015-08-12 14:40 ` Oleg Nesterov
2015-08-12 15:11 ` Eric W. Biederman
2015-08-12 1:22 ` [PATCH 0/2] userns: Creation logic fixes Eric W. Biederman
2015-08-12 1:24 ` [PATCH 1/2] unshare: Unsharing a thread does not require unsharing a vm Eric W. Biederman
2015-08-12 17:48 ` Oleg Nesterov
2015-08-12 18:39 ` Eric W. Biederman
2015-08-13 12:55 ` Oleg Nesterov [this message]
2015-08-13 15:38 ` Eric W. Biederman
2015-08-13 16:17 ` Oleg Nesterov
2015-08-13 16:27 ` Eric W. Biederman
2015-08-13 16:50 ` Oleg Nesterov
2015-08-14 17:59 ` Oleg Nesterov
2015-08-12 19:59 ` [PATCH v2] " Eric W. Biederman
2015-08-13 12:57 ` Oleg Nesterov
2015-08-13 16:01 ` Eric W. Biederman
2015-08-13 16:30 ` Oleg Nesterov
2015-08-13 16:39 ` Eric W. Biederman
2015-08-12 1:25 ` [PATCH 2/2] userns,pidns: Force thread group sharing, not signal handler sharing Eric W. Biederman
2015-08-12 17:24 ` Oleg Nesterov
2015-08-12 6:29 ` [PATCH 0/2] userns: Creation logic fixes Kees Cook
2015-08-06 14:35 ` [PATCH] user_ns: use correct check for single-threadedness Oleg Nesterov
2015-08-06 21:16 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150813125550.GA13984@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=dhowells@redhat.com \
--cc=ebiederm@xmission.com \
--cc=jln@google.com \
--cc=keescook@chromium.org \
--cc=kirill.shutemov@linux.intel.com \
--cc=kirill@shutemov.name \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=rickyz@chromium.org \
--cc=riel@redhat.com \
--cc=vdavydov@parallels.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.