Linux Container Development
 help / color / mirror / Atom feed
* [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]           ` <8737crt4dz.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
@ 2017-04-29 19:25             ` Eric W. Biederman
       [not found]               ` <20170429205325.GB1119@mail.hallyn.com>
                                 ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Eric W. Biederman @ 2017-04-29 19:25 UTC (permalink / raw)
  To: Linux Containers
  Cc: paul-r2n+y4ga6xFZroRs9YW3xA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gorcunov-GEFAQzZX7r8dnm+yROfE0A, luto-kltTT9wpgjJwATOyAt5JVQ,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	serge-A9i7LUbDfNHQT0dZR+AlfA, mingo-DgEjT+Ai2ygdnm+yROfE0A,
	Kirill Tkhai, agruenba-H+wXaHxf7aLQT0dZR+AlfA


It is pointless and confusing to allow a pid namespace hierarchy and
the user namespace hierarchy to get out of sync.  The owner of a child
pid namespace should be the owner of the parent pid namespace or
a descendant of the owner of the parent pid namespace.

Otherwise it is possible to construct scenarios where it is legal to
do something in a parent pid namespace but in a child pid namespace.

It requires use of setns into a pid namespace (but not into a user
namespace) to create such a scenario.

Add the function in_userns to help in making this determination.

Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---

While review a patch from Kiril Tkhai I realized we were missing this
sanity check....

 include/linux/user_namespace.h |  8 +++++++-
 kernel/pid_namespace.c         |  4 ++++
 kernel/user_namespace.c        | 18 ++++++++++++------
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 32354b4b4b2b..497ed50004db 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -112,8 +112,9 @@ extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t,
 extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
 extern int proc_setgroups_show(struct seq_file *m, void *v);
 extern bool userns_may_setgroups(const struct user_namespace *ns);
+extern bool in_userns(const struct user_namespace *ancestor,
+		       const struct user_namespace *child);
 extern bool current_in_userns(const struct user_namespace *target_ns);
-
 struct ns_common *ns_get_owner(struct ns_common *ns);
 #else
 
@@ -144,6 +145,11 @@ static inline bool userns_may_setgroups(const struct user_namespace *ns)
 	return true;
 }
 
+static inline bool in_userns(const struct user_namespace *target_ns)
+{
+	return true;
+}
+
 static inline bool current_in_userns(const struct user_namespace *target_ns)
 {
 	return true;
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index de461aa0bf9a..749147f5a613 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -101,6 +101,10 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
 	int i;
 	int err;
 
+	err = -EINVAL;
+	if (!in_userns(parent_pid_ns->user_ns, user_ns))
+		goto out;
+
 	err = -ENOSPC;
 	if (level > MAX_PID_NS_LEVEL)
 		goto out;
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 2f735cbe05e8..7d8658fbabc8 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -986,19 +986,25 @@ bool userns_may_setgroups(const struct user_namespace *ns)
 }
 
 /*
- * Returns true if @ns is the same namespace as or a descendant of
- * @target_ns.
+ * Returns true if @child is the same namespace or a descendant of
+ * @ancestor.
  */
-bool current_in_userns(const struct user_namespace *target_ns)
+bool in_userns(const struct user_namespace *ancestor,
+	       const struct user_namespace *child)
 {
-	struct user_namespace *ns;
-	for (ns = current_user_ns(); ns; ns = ns->parent) {
-		if (ns == target_ns)
+	const struct user_namespace *ns;
+	for (ns = child; ns; ns = ns->parent) {
+		if (ns == ancestor)
 			return true;
 	}
 	return false;
 }
 
+bool current_in_userns(const struct user_namespace *target_ns)
+{
+	return in_userns(target_ns, current_user_ns());
+}
+
 static inline struct user_namespace *to_user_ns(struct ns_common *ns)
 {
 	return container_of(ns, struct user_namespace, ns);
-- 
2.10.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]               ` <87vapnrp7f.fsf_-_-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
@ 2017-04-29 20:53                 ` Serge E. Hallyn
  2017-05-02 10:03                 ` Kirill Tkhai
  1 sibling, 0 replies; 7+ messages in thread
From: Serge E. Hallyn @ 2017-04-29 20:53 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: agruenba-H+wXaHxf7aLQT0dZR+AlfA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, Linux Containers,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	paul-r2n+y4ga6xFZroRs9YW3xA, Kirill Tkhai,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	luto-kltTT9wpgjJwATOyAt5JVQ, gorcunov-GEFAQzZX7r8dnm+yROfE0A,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, serge-A9i7LUbDfNHQT0dZR+AlfA

Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
> 
> It is pointless and confusing to allow a pid namespace hierarchy and
> the user namespace hierarchy to get out of sync.  The owner of a child
> pid namespace should be the owner of the parent pid namespace or
> a descendant of the owner of the parent pid namespace.
> 
> Otherwise it is possible to construct scenarios where it is legal to
> do something in a parent pid namespace but in a child pid namespace.

Hi,

did you mean 'but not in a child...' above?

> It requires use of setns into a pid namespace (but not into a user
> namespace) to create such a scenario.
> 
> Add the function in_userns to help in making this determination.
> 
> Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
> ---
> 
> While review a patch from Kiril Tkhai I realized we were missing this
> sanity check....
> 
>  include/linux/user_namespace.h |  8 +++++++-
>  kernel/pid_namespace.c         |  4 ++++
>  kernel/user_namespace.c        | 18 ++++++++++++------
>  3 files changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
> index 32354b4b4b2b..497ed50004db 100644
> --- a/include/linux/user_namespace.h
> +++ b/include/linux/user_namespace.h
> @@ -112,8 +112,9 @@ extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t,
>  extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
>  extern int proc_setgroups_show(struct seq_file *m, void *v);
>  extern bool userns_may_setgroups(const struct user_namespace *ns);
> +extern bool in_userns(const struct user_namespace *ancestor,
> +		       const struct user_namespace *child);
>  extern bool current_in_userns(const struct user_namespace *target_ns);
> -
>  struct ns_common *ns_get_owner(struct ns_common *ns);
>  #else
>  
> @@ -144,6 +145,11 @@ static inline bool userns_may_setgroups(const struct user_namespace *ns)
>  	return true;
>  }
>  
> +static inline bool in_userns(const struct user_namespace *target_ns)
> +{
> +	return true;
> +}
> +
>  static inline bool current_in_userns(const struct user_namespace *target_ns)
>  {
>  	return true;
> diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
> index de461aa0bf9a..749147f5a613 100644
> --- a/kernel/pid_namespace.c
> +++ b/kernel/pid_namespace.c
> @@ -101,6 +101,10 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
>  	int i;
>  	int err;
>  
> +	err = -EINVAL;
> +	if (!in_userns(parent_pid_ns->user_ns, user_ns))
> +		goto out;
> +
>  	err = -ENOSPC;
>  	if (level > MAX_PID_NS_LEVEL)
>  		goto out;
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 2f735cbe05e8..7d8658fbabc8 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -986,19 +986,25 @@ bool userns_may_setgroups(const struct user_namespace *ns)
>  }
>  
>  /*
> - * Returns true if @ns is the same namespace as or a descendant of
> - * @target_ns.
> + * Returns true if @child is the same namespace or a descendant of
> + * @ancestor.
>   */
> -bool current_in_userns(const struct user_namespace *target_ns)
> +bool in_userns(const struct user_namespace *ancestor,
> +	       const struct user_namespace *child)
>  {
> -	struct user_namespace *ns;
> -	for (ns = current_user_ns(); ns; ns = ns->parent) {
> -		if (ns == target_ns)
> +	const struct user_namespace *ns;
> +	for (ns = child; ns; ns = ns->parent) {
> +		if (ns == ancestor)
>  			return true;
>  	}
>  	return false;
>  }
>  
> +bool current_in_userns(const struct user_namespace *target_ns)
> +{
> +	return in_userns(target_ns, current_user_ns());
> +}
> +
>  static inline struct user_namespace *to_user_ns(struct ns_common *ns)
>  {
>  	return container_of(ns, struct user_namespace, ns);
> -- 
> 2.10.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]                 ` <20170429205325.GB1119-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
@ 2017-04-30  4:33                   ` Eric W. Biederman
       [not found]                     ` <87a86yseej.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2017-04-30  4:33 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: paul-r2n+y4ga6xFZroRs9YW3xA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, Linux Containers,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gorcunov-GEFAQzZX7r8dnm+yROfE0A, Kirill Tkhai,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	luto-kltTT9wpgjJwATOyAt5JVQ, mingo-DgEjT+Ai2ygdnm+yROfE0A,
	agruenba-H+wXaHxf7aLQT0dZR+AlfA

"Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:

> Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
>> 
>> It is pointless and confusing to allow a pid namespace hierarchy and
>> the user namespace hierarchy to get out of sync.  The owner of a child
>> pid namespace should be the owner of the parent pid namespace or
>> a descendant of the owner of the parent pid namespace.
>> 
>> Otherwise it is possible to construct scenarios where it is legal to
>> do something in a parent pid namespace but in a child pid namespace.
>
> Hi,
>
> did you mean 'but not in a child...' above?

Actually I believe I meant:

>> Otherwise it is possible to construct scenarios where it is not legal
>> to do something in a parent pid namespace but it is legal a child pid
>> namespace.

I definitely need to fix that wording thank you.

Eric

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]                     ` <87a86yseej.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
@ 2017-04-30  4:42                       ` Eric W. Biederman
  0 siblings, 0 replies; 7+ messages in thread
From: Eric W. Biederman @ 2017-04-30  4:42 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: paul-r2n+y4ga6xFZroRs9YW3xA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, Linux Containers,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gorcunov-GEFAQzZX7r8dnm+yROfE0A, Kirill Tkhai,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	luto-kltTT9wpgjJwATOyAt5JVQ, mingo-DgEjT+Ai2ygdnm+yROfE0A,
	agruenba-H+wXaHxf7aLQT0dZR+AlfA

ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org (Eric W. Biederman) writes:

> "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:
>
>> Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
>>> 
>>> It is pointless and confusing to allow a pid namespace hierarchy and
>>> the user namespace hierarchy to get out of sync.  The owner of a child
>>> pid namespace should be the owner of the parent pid namespace or
>>> a descendant of the owner of the parent pid namespace.
>>> 
>>> Otherwise it is possible to construct scenarios where it is legal to
>>> do something in a parent pid namespace but in a child pid namespace.
>>
>> Hi,
>>
>> did you mean 'but not in a child...' above?
>
> Actually I believe I meant:
>
>>> Otherwise it is possible to construct scenarios where it is not legal
>>> to do something in a parent pid namespace but it is legal a child pid
>>> namespace.
>
> I definitely need to fix that wording thank you.

Looking at some more I mean:

Otherwise it is possible to construct scenarios where a process has a
capability in a over a parent pid namespace but does not have the
capability over a child pid namespace.  Which confusingly makes
permission checks non-transitive.


Eric

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]               ` <87vapnrp7f.fsf_-_-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
  2017-04-29 20:53                 ` Serge E. Hallyn
@ 2017-05-02 10:03                 ` Kirill Tkhai
  1 sibling, 0 replies; 7+ messages in thread
From: Kirill Tkhai @ 2017-05-02 10:03 UTC (permalink / raw)
  To: Eric W. Biederman, Linux Containers
  Cc: paul-r2n+y4ga6xFZroRs9YW3xA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gorcunov-GEFAQzZX7r8dnm+yROfE0A, luto-kltTT9wpgjJwATOyAt5JVQ,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	serge-A9i7LUbDfNHQT0dZR+AlfA, mingo-DgEjT+Ai2ygdnm+yROfE0A,
	agruenba-H+wXaHxf7aLQT0dZR+AlfA



On 29.04.2017 22:25, Eric W. Biederman wrote:
> 
> It is pointless and confusing to allow a pid namespace hierarchy and
> the user namespace hierarchy to get out of sync.  The owner of a child
> pid namespace should be the owner of the parent pid namespace or
> a descendant of the owner of the parent pid namespace.
> 
> Otherwise it is possible to construct scenarios where it is legal to
> do something in a parent pid namespace but in a child pid namespace.
> 
> It requires use of setns into a pid namespace (but not into a user
> namespace) to create such a scenario.
> 
> Add the function in_userns to help in making this determination.
> 
> Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
> ---
> 
> While review a patch from Kiril Tkhai I realized we were missing this
> sanity check....
> 
>  include/linux/user_namespace.h |  8 +++++++-
>  kernel/pid_namespace.c         |  4 ++++
>  kernel/user_namespace.c        | 18 ++++++++++++------
>  3 files changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
> index 32354b4b4b2b..497ed50004db 100644
> --- a/include/linux/user_namespace.h
> +++ b/include/linux/user_namespace.h
> @@ -112,8 +112,9 @@ extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t,
>  extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
>  extern int proc_setgroups_show(struct seq_file *m, void *v);
>  extern bool userns_may_setgroups(const struct user_namespace *ns);
> +extern bool in_userns(const struct user_namespace *ancestor,
> +		       const struct user_namespace *child);
>  extern bool current_in_userns(const struct user_namespace *target_ns);
> -
>  struct ns_common *ns_get_owner(struct ns_common *ns);
>  #else
>  
> @@ -144,6 +145,11 @@ static inline bool userns_may_setgroups(const struct user_namespace *ns)
>  	return true;
>  }
>  
> +static inline bool in_userns(const struct user_namespace *target_ns)
> +{
> +	return true;
> +}
> +
>  static inline bool current_in_userns(const struct user_namespace *target_ns)
>  {
>  	return true;
> diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
> index de461aa0bf9a..749147f5a613 100644
> --- a/kernel/pid_namespace.c
> +++ b/kernel/pid_namespace.c
> @@ -101,6 +101,10 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
>  	int i;
>  	int err;
>  
> +	err = -EINVAL;
> +	if (!in_userns(parent_pid_ns->user_ns, user_ns))
> +		goto out;
> +
>  	err = -ENOSPC;
>  	if (level > MAX_PID_NS_LEVEL)
>  		goto out;
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 2f735cbe05e8..7d8658fbabc8 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -986,19 +986,25 @@ bool userns_may_setgroups(const struct user_namespace *ns)
>  }
>  
>  /*
> - * Returns true if @ns is the same namespace as or a descendant of
> - * @target_ns.
> + * Returns true if @child is the same namespace or a descendant of
> + * @ancestor.
>   */
> -bool current_in_userns(const struct user_namespace *target_ns)
> +bool in_userns(const struct user_namespace *ancestor,
> +	       const struct user_namespace *child)
>  {
> -	struct user_namespace *ns;
> -	for (ns = current_user_ns(); ns; ns = ns->parent) {
> -		if (ns == target_ns)
> +	const struct user_namespace *ns;
> +	for (ns = child; ns; ns = ns->parent) {
> +		if (ns == ancestor)
>  			return true;
>  	}
>  	return false;
>  }

We have user_namespace::level, so it's possible to stop iterations earlier
and save some cpu cycles:

	for (ns = child; ns->level >= ancestor->level; ns = ns->parent)
		;
	return (ns == ancestor);

>  
> +bool current_in_userns(const struct user_namespace *target_ns)
> +{
> +	return in_userns(target_ns, current_user_ns());
> +}
> +
>  static inline struct user_namespace *to_user_ns(struct ns_common *ns)
>  {
>  	return container_of(ns, struct user_namespace, ns);
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]                 ` <d67c8c06-2e6b-9cc0-df81-71d3cf4bb43d-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>
@ 2017-05-02 10:04                   ` Kirill Tkhai
  0 siblings, 0 replies; 7+ messages in thread
From: Kirill Tkhai @ 2017-05-02 10:04 UTC (permalink / raw)
  To: Eric W. Biederman, Linux Containers
  Cc: paul-r2n+y4ga6xFZroRs9YW3xA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gorcunov-GEFAQzZX7r8dnm+yROfE0A, luto-kltTT9wpgjJwATOyAt5JVQ,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	serge-A9i7LUbDfNHQT0dZR+AlfA, mingo-DgEjT+Ai2ygdnm+yROfE0A,
	agruenba-H+wXaHxf7aLQT0dZR+AlfA


On 02.05.2017 13:03, Kirill Tkhai wrote:
> 
> 
> On 29.04.2017 22:25, Eric W. Biederman wrote:
>>
>> It is pointless and confusing to allow a pid namespace hierarchy and
>> the user namespace hierarchy to get out of sync.  The owner of a child
>> pid namespace should be the owner of the parent pid namespace or
>> a descendant of the owner of the parent pid namespace.
>>
>> Otherwise it is possible to construct scenarios where it is legal to
>> do something in a parent pid namespace but in a child pid namespace.
>>
>> It requires use of setns into a pid namespace (but not into a user
>> namespace) to create such a scenario.
>>
>> Add the function in_userns to help in making this determination.
>>
>> Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
>> ---
>>
>> While review a patch from Kiril Tkhai I realized we were missing this
>> sanity check....
>>
>>  include/linux/user_namespace.h |  8 +++++++-
>>  kernel/pid_namespace.c         |  4 ++++
>>  kernel/user_namespace.c        | 18 ++++++++++++------
>>  3 files changed, 23 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
>> index 32354b4b4b2b..497ed50004db 100644
>> --- a/include/linux/user_namespace.h
>> +++ b/include/linux/user_namespace.h
>> @@ -112,8 +112,9 @@ extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t,
>>  extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *);
>>  extern int proc_setgroups_show(struct seq_file *m, void *v);
>>  extern bool userns_may_setgroups(const struct user_namespace *ns);
>> +extern bool in_userns(const struct user_namespace *ancestor,
>> +		       const struct user_namespace *child);
>>  extern bool current_in_userns(const struct user_namespace *target_ns);
>> -
>>  struct ns_common *ns_get_owner(struct ns_common *ns);
>>  #else
>>  
>> @@ -144,6 +145,11 @@ static inline bool userns_may_setgroups(const struct user_namespace *ns)
>>  	return true;
>>  }
>>  
>> +static inline bool in_userns(const struct user_namespace *target_ns)
>> +{
>> +	return true;
>> +}
>> +
>>  static inline bool current_in_userns(const struct user_namespace *target_ns)
>>  {
>>  	return true;
>> diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
>> index de461aa0bf9a..749147f5a613 100644
>> --- a/kernel/pid_namespace.c
>> +++ b/kernel/pid_namespace.c
>> @@ -101,6 +101,10 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
>>  	int i;
>>  	int err;
>>  
>> +	err = -EINVAL;
>> +	if (!in_userns(parent_pid_ns->user_ns, user_ns))
>> +		goto out;
>> +
>>  	err = -ENOSPC;
>>  	if (level > MAX_PID_NS_LEVEL)
>>  		goto out;
>> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
>> index 2f735cbe05e8..7d8658fbabc8 100644
>> --- a/kernel/user_namespace.c
>> +++ b/kernel/user_namespace.c
>> @@ -986,19 +986,25 @@ bool userns_may_setgroups(const struct user_namespace *ns)
>>  }
>>  
>>  /*
>> - * Returns true if @ns is the same namespace as or a descendant of
>> - * @target_ns.
>> + * Returns true if @child is the same namespace or a descendant of
>> + * @ancestor.
>>   */
>> -bool current_in_userns(const struct user_namespace *target_ns)
>> +bool in_userns(const struct user_namespace *ancestor,
>> +	       const struct user_namespace *child)
>>  {
>> -	struct user_namespace *ns;
>> -	for (ns = current_user_ns(); ns; ns = ns->parent) {
>> -		if (ns == target_ns)
>> +	const struct user_namespace *ns;
>> +	for (ns = child; ns; ns = ns->parent) {
>> +		if (ns == ancestor)
>>  			return true;
>>  	}
>>  	return false;
>>  }
> 
> We have user_namespace::level, so it's possible to stop iterations earlier
> and save some cpu cycles:
> 
> 	for (ns = child; ns->level >= ancestor->level; ns = ns->parent)

Just ">" here.

> 		;
> 	return (ns == ancestor);
> 
>>  
>> +bool current_in_userns(const struct user_namespace *target_ns)
>> +{
>> +	return in_userns(target_ns, current_user_ns());
>> +}
>> +
>>  static inline struct user_namespace *to_user_ns(struct ns_common *ns)
>>  {
>>  	return container_of(ns, struct user_namespace, ns);
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] userns,pidns: Verify the userns for new pid namespaces
       [not found]                   ` <fab323b8-a909-bbce-77d2-afbcd3b0452e-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>
@ 2017-05-02 20:39                     ` Eric W. Biederman
  0 siblings, 0 replies; 7+ messages in thread
From: Eric W. Biederman @ 2017-05-02 20:39 UTC (permalink / raw)
  To: Kirill Tkhai
  Cc: agruenba-H+wXaHxf7aLQT0dZR+AlfA, keescook-F7+t8E8rja9g9hUCZPvPmw,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, Linux Containers,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	paul-r2n+y4ga6xFZroRs9YW3xA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	avagin-GEFAQzZX7r8dnm+yROfE0A, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	luto-kltTT9wpgjJwATOyAt5JVQ, gorcunov-GEFAQzZX7r8dnm+yROfE0A,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, serge-A9i7LUbDfNHQT0dZR+AlfA

Kirill Tkhai <ktkhai-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org> writes:
>>> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
>>> index 2f735cbe05e8..7d8658fbabc8 100644
>>> --- a/kernel/user_namespace.c
>>> +++ b/kernel/user_namespace.c
>>> @@ -986,19 +986,25 @@ bool userns_may_setgroups(const struct user_namespace *ns)
>>>  }
>>>  
>>>  /*
>>> - * Returns true if @ns is the same namespace as or a descendant of
>>> - * @target_ns.
>>> + * Returns true if @child is the same namespace or a descendant of
>>> + * @ancestor.
>>>   */
>>> -bool current_in_userns(const struct user_namespace *target_ns)
>>> +bool in_userns(const struct user_namespace *ancestor,
>>> +	       const struct user_namespace *child)
>>>  {
>>> -	struct user_namespace *ns;
>>> -	for (ns = current_user_ns(); ns; ns = ns->parent) {
>>> -		if (ns == target_ns)
>>> +	const struct user_namespace *ns;
>>> +	for (ns = child; ns; ns = ns->parent) {
>>> +		if (ns == ancestor)
>>>  			return true;
>>>  	}
>>>  	return false;
>>>  }
>> 
>> We have user_namespace::level, so it's possible to stop iterations earlier
>> and save some cpu cycles:
>> 
>> 	for (ns = child; ns->level >= ancestor->level; ns = ns->parent)
>
> Just ">" here.
>
>> 		;
>> 	return (ns == ancestor);

Good observation.  Thank you.

Eric

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-05-02 20:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <149329634856.21195.14196911999722279118.stgit@localhost.localdomain>
     [not found] ` <87mvb16fv7.fsf@xmission.com>
     [not found]   ` <12a73543-79ea-4bac-7e96-6ab237534af2@virtuozzo.com>
     [not found]     ` <877f254yx0.fsf@xmission.com>
     [not found]       ` <a9941daf-861b-453c-37b8-e95389a9959b@virtuozzo.com>
     [not found]         ` <8737crt4dz.fsf@xmission.com>
     [not found]           ` <8737crt4dz.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2017-04-29 19:25             ` [PATCH] userns,pidns: Verify the userns for new pid namespaces Eric W. Biederman
     [not found]               ` <20170429205325.GB1119@mail.hallyn.com>
     [not found]                 ` <20170429205325.GB1119-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
2017-04-30  4:33                   ` Eric W. Biederman
     [not found]                     ` <87a86yseej.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2017-04-30  4:42                       ` Eric W. Biederman
     [not found]               ` <87vapnrp7f.fsf_-_-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2017-04-29 20:53                 ` Serge E. Hallyn
2017-05-02 10:03                 ` Kirill Tkhai
     [not found]               ` <d67c8c06-2e6b-9cc0-df81-71d3cf4bb43d@virtuozzo.com>
     [not found]                 ` <d67c8c06-2e6b-9cc0-df81-71d3cf4bb43d-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>
2017-05-02 10:04                   ` Kirill Tkhai
     [not found]                 ` <fab323b8-a909-bbce-77d2-afbcd3b0452e@virtuozzo.com>
     [not found]                   ` <fab323b8-a909-bbce-77d2-afbcd3b0452e-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>
2017-05-02 20:39                     ` Eric W. Biederman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox