mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: David Howells <dhowells@redhat.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>,
	LSM <linux-security-module@vger.kernel.org>,
	Andrew Morton <akpm@osdl.org>, James Morris <jmorris@namei.org>,
	Kees Cook <kees.cook@canonical.com>,
	containers@lists.linux-foundation.org,
	kernel list <linux-kernel@vger.kernel.org>,
	Alexey Dobriyan <adobriyan@gmail.com>,
	Michael Kerrisk <mtk.manpages@gmail.com>,
	xemul@parallels.com
Subject: Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
Date: Wed, 23 Feb 2011 13:21:28 -0800	[thread overview]
Message-ID: <m1lj16ih0n.fsf@fess.ebiederm.org> (raw)
In-Reply-To: <3139.1298481393@redhat.com> (David Howells's message of "Wed, 23 Feb 2011 17:16:33 +0000")

David Howells <dhowells@redhat.com> writes:

> Serge E. Hallyn <serge@hallyn.com> wrote:
>
>>  struct uts_namespace {
>>  	struct kref kref;
>>  	struct new_utsname name;
>> +	struct user_namespace *user_ns;
>>  };
>
> If a uts_namespace belongs to a user_namespace, should CLONE_NEWUSER then
> imply CLONE_NEWUTS?
>
> Or is uts_namespace::user_ns more an implication that the set of users in
> user_namespace are the only ones authorised to alter the uts data.

The later.

> I presume that the uts_namespace of a process must be owned by one of the
> user_namespaces in the alternating inheritance chain of namespaces and their
> creators leading from current_user_ns() to init_user_ns.
>
> With that in mind, looking at patch 3:
>
> -	if (!capable(CAP_SYS_ADMIN))
> +	if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
>
> what is it you're actually asking?  I presume it's 'does this user have
> CAP_SYS_ADMIN capability over objects belonging to the uts_namespace's
> user_namespace?'

Yes.

> So, to look at the important bit of patch 2:
>
> -int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap,
> -		int audit)
> +int cap_capable(struct task_struct *tsk, const struct cred *cred,
> +		struct user_namespace *targ_ns, int cap, int audit)
>  {
> -	return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
> +	for (;;) {
> +		/* The creator of the user namespace has all caps. */
> +		if (targ_ns != &init_user_ns && targ_ns->creator == cred->user)
> +			return 0;
> +
> +		/* Do we have the necessary capabilities? */
> +		if (targ_ns == cred->user->user_ns)
> +			return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
> +
> +		/* Have we tried all of the parent namespaces? */
> +		if (targ_ns == &init_user_ns)
> +			return -EPERM;
> +
> +		/* If you have the capability in a parent user ns you have it
> +		 * in the over all children user namespaces as well, so see
> +		 * if this process has the capability in the parent user
> +		 * namespace.
> +		 */
> +		targ_ns = targ_ns->creator->user_ns;
> +	}
> +
> +	/* We never get here */
> +	return -EPERM;
>  }
>
> On entry, as we're called from ns_capable(), cred->user is the user that the
> current process is running as, and, as such, may be in a separate namespace
> from uts_namespace - which may itself be in a separate namespace from
> init_user_ns.
>
> So, assume for the sake of argument that there are three user_namespaces along
> the chain from the calling process to the root, and that the uts_namespace
> belongs to the middle one.

So we have the nested stack of:
user_ns3->creator->user_ns == user_ns2
user_ns2->creator->user_ns == &init_user_ns
uts_ns2->user_ns == user_ns2

>
> 		if (targ_ns != &init_user_ns && targ_ns->creator == cred->user)
> 			return 0;
>
> Can never match because targ_ns->creator cannot be cred->user; even if the
> uts_namespace belongs to our namespace, given that the creator lies outside
> our namespace.

Initially we come in with targ_ns == user_ns2 and cred->user->user_ns in
one of (user_ns3, user_ns2, or &init_user_ns).

targ_ns takes on values user_ns2 and &init_user_ns.

So when targ_ns becomes &init_user_ns.  If the user in question is
uts_ns2->user_ns->creator.  This check will indeed match.

> 		if (targ_ns == cred->user->user_ns)
> 			return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
>
> Can only match if we are in the target user_namespace (ie. the one to which
> uts_namespace belongs), whether or not we have CAP_SYS_ADMIN.

As before targ_ns takes on values of user_ns2 and &init_user_ns.

Which means this check will match if we have CAP_SYS_ADMIN in
&init_user_ns or in user_ns2.

> Which means that unless the uts_namespace belongs to our user_namespace, we
> cannot change it.  Is that correct?

No.  If you are root in a parent namespace you can also change it.

> So ns_capable() restricts you to only doing interesting things to objects that
> belong to a user_namespace if they are in your own user_namespace.  Is that
> correct?

No.  Root outside your user namespace is also allowed to do interesting
things.

> If that is so, is the loop required for ns_capable()?

Yes.


> Looking further at patch 2:
>
> 	#define nsown_capable(cap) (ns_capable(current_user_ns(), (cap)))
>
> Given what I've said above, I presume the loop isn't necessary here either.
>
>
> I think you're using ns_capable() in two different ways:
>
>  (1) You're using it to see if a process has power over its descendents in a
>      user_namespace that can be traced back to a clone() that it did with
>      CLONE_NEWUSER.
>
>      For example, automatically granting a process permission to kill
>      descendents in a namespace it created.
>
>  (2) You're using it to see if a process can access objects that might be
>      outside its own user_namespace.
>
>      For example, setting the hostname.
>
> Is it worth giving two different interfaces to make this clearer (even if they
> actually do the same thing)?
>
>
> Sorry if this seems rambly, but I'm trying to get my head round your
> code.

I am all for making that loop a little clearer, because it is something
you have to pause and think about to understand but so far I don't think
the loop is wrong, and it is simple.

Eric

  reply	other threads:[~2011-02-23 21:21 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-17 15:02 userns: targeted capabilities v5 Serge E. Hallyn
2011-02-17 15:02 ` [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace Serge E. Hallyn
2011-02-18  3:31   ` Eric W. Biederman
2011-02-18 16:57   ` Daniel Lezcano
2011-02-18 23:59   ` Andrew Morton
2011-02-17 15:03 ` [PATCH 2/9] security: Make capabilities relative to the user namespace Serge E. Hallyn
2011-02-18  3:46   ` Eric W. Biederman
2011-02-18 23:44   ` Daniel Lezcano
2011-02-18 23:59   ` Andrew Morton
2011-02-17 15:03 ` [PATCH 3/9] allow sethostname in a container Serge E. Hallyn
2011-02-18  3:05   ` Eric W. Biederman
2011-02-18 23:46   ` Daniel Lezcano
2011-02-17 15:03 ` [PATCH 4/9] allow killing tasks in your own or child userns Serge E. Hallyn
2011-02-18  3:00   ` Eric W. Biederman
2011-02-18 23:59   ` Andrew Morton
2011-02-24  0:48     ` Serge E. Hallyn
2011-02-24  0:54       ` Andrew Morton
2011-02-19 10:55   ` Daniel Lezcano
2011-02-17 15:03 ` [PATCH 5/9] Allow ptrace from non-init user namespaces Serge E. Hallyn
2011-02-18  2:59   ` Eric W. Biederman
2011-02-18  4:36     ` Serge E. Hallyn
2011-02-24  0:49       ` [PATCH] userns: ptrace: incorporate feedback from Eric Serge E. Hallyn
2011-02-24  0:56         ` Andrew Morton
2011-02-24  3:15           ` Serge E. Hallyn
2011-02-18 23:59   ` [PATCH 5/9] Allow ptrace from non-init user namespaces Andrew Morton
2011-02-24  0:43     ` Serge E. Hallyn
2011-02-19 17:49   ` Daniel Lezcano
2011-02-17 15:03 ` [PATCH 6/9] user namespaces: convert all capable checks in kernel/sys.c Serge E. Hallyn
2011-02-18  1:57   ` Eric W. Biederman
2011-02-18 23:59   ` Andrew Morton
2011-02-19  0:01   ` Andrew Morton
2011-02-19 17:52   ` Daniel Lezcano
2011-02-17 15:03 ` [PATCH 7/9] add a user namespace owner of ipc ns Serge E. Hallyn
2011-02-18  3:19   ` Eric W. Biederman
2011-02-18 23:59   ` Andrew Morton
2011-02-19 17:57   ` Daniel Lezcano
2011-02-17 15:03 ` [PATCH 8/9] user namespaces: convert several capable() calls Serge E. Hallyn
2011-02-18  1:51   ` Eric W. Biederman
2011-02-19 19:07   ` Daniel Lezcano
2011-02-17 15:04 ` [PATCH 9/9] userns: check user namespace for task->file uid equivalence checks Serge E. Hallyn
2011-02-18  1:29   ` Eric W. Biederman
2011-02-18 23:59   ` Andrew Morton
2011-02-24  3:24     ` Serge E. Hallyn
2011-02-24  5:08       ` Andrew Morton
2011-02-19 19:22   ` Daniel Lezcano
2011-02-18  0:21 ` userns: targeted capabilities v5 Andrew Morton
2011-02-18  3:53   ` Eric W. Biederman
2011-02-18  4:28   ` Serge E. Hallyn
2011-02-23 11:40 ` [PATCH 2/9] security: Make capabilities relative to the user namespace David Howells
2011-02-23 12:01 ` David Howells
2011-02-23 13:43   ` Serge E. Hallyn
2011-02-23 12:05 ` User namespaces and keys David Howells
2011-02-23 13:58   ` Serge E. Hallyn
2011-02-23 14:46     ` Eric W. Biederman
2011-02-23 15:06   ` David Howells
2011-02-23 15:45     ` Eric W. Biederman
2011-02-23 15:53       ` Serge E. Hallyn
2011-02-23 19:24         ` Casey Schaufler
2011-02-23 20:55           ` Eric W. Biederman
2011-02-23 21:37             ` Casey Schaufler
2011-02-24  6:56               ` Eric W. Biederman
2011-02-23 16:59 ` [PATCH 2/9] security: Make capabilities relative to the user namespace David Howells
2011-02-23 17:05 ` [PATCH 5/9] Allow ptrace from non-init user namespaces David Howells
2011-02-23 17:11 ` David Howells
2011-02-23 17:16 ` [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace David Howells
2011-02-23 21:21   ` Eric W. Biederman [this message]
2011-02-23 23:19   ` David Howells
2011-02-23 23:54     ` 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=m1lj16ih0n.fsf@fess.ebiederm.org \
    --to=ebiederm@xmission.com \
    --cc=adobriyan@gmail.com \
    --cc=akpm@osdl.org \
    --cc=containers@lists.linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=jmorris@namei.org \
    --cc=kees.cook@canonical.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mtk.manpages@gmail.com \
    --cc=serge@hallyn.com \
    --cc=xemul@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome