All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Serge E. Hallyn" <serge@hallyn.com>
To: Christian Brauner <christian.brauner@ubuntu.com>
Cc: "Stéphane Graber" <stgraber@ubuntu.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	"Aleksa Sarai" <cyphar@cyphar.com>,
	"Jann Horn" <jannh@google.com>,
	smbarber@chromium.org,
	"Seth Forshee" <seth.forshee@canonical.com>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	"Alexey Dobriyan" <adobriyan@gmail.com>,
	"Serge Hallyn" <serge@hallyn.com>,
	"James Morris" <jmorris@namei.org>,
	"Kees Cook" <keescook@chromium.org>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Phil Estes" <estesp@gmail.com>,
	linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	containers@lists.linux-foundation.org,
	linux-security-module@vger.kernel.org, linux-api@vger.kernel.org
Subject: Re: [PATCH v3 01/25] user_namespace: introduce fsid mappings infrastructure
Date: Tue, 18 Feb 2020 20:33:26 -0600	[thread overview]
Message-ID: <20200219023326.GA19144@mail.hallyn.com> (raw)
In-Reply-To: <20200218143411.2389182-2-christian.brauner@ubuntu.com>

On Tue, Feb 18, 2020 at 03:33:47PM +0100, Christian Brauner wrote:
> This introduces the infrastructure to setup fsid mappings which will be used in
> later patches.
> All new code depends on CONFIG_USER_NS_FSID=y. It currently defaults to "N".
> If CONFIG_USER_NS_FSID is not set, no new code is added.
> 
> In this patch fsuid_m_show() and fsgid_m_show() are introduced. They are
> identical to uid_m_show() and gid_m_show() until we introduce from_kfsuid() and
> from_kfsgid() in a follow-up patch.
> 
> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>

Acked-by: Serge Hallyn <serge@hallyn.com>

> ---
> /* v2 */
> - Randy Dunlap <rdunlap@infradead.org>:
>   - Fix typo in USER_NS_FSID kconfig documentation.
> 
> /* v3 */
> unchanged
> ---
>  include/linux/user_namespace.h |  10 +++
>  init/Kconfig                   |  11 +++
>  kernel/user.c                  |  22 ++++++
>  kernel/user_namespace.c        | 122 +++++++++++++++++++++++++++++++++
>  4 files changed, 165 insertions(+)
> 
> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
> index 6ef1c7109fc4..e44742b0cf8a 100644
> --- a/include/linux/user_namespace.h
> +++ b/include/linux/user_namespace.h
> @@ -56,6 +56,10 @@ enum ucount_type {
>  struct user_namespace {
>  	struct uid_gid_map	uid_map;
>  	struct uid_gid_map	gid_map;
> +#ifdef CONFIG_USER_NS_FSID
> +	struct uid_gid_map	fsuid_map;
> +	struct uid_gid_map	fsgid_map;
> +#endif
>  	struct uid_gid_map	projid_map;
>  	atomic_t		count;
>  	struct user_namespace	*parent;
> @@ -127,6 +131,12 @@ struct seq_operations;
>  extern const struct seq_operations proc_uid_seq_operations;
>  extern const struct seq_operations proc_gid_seq_operations;
>  extern const struct seq_operations proc_projid_seq_operations;
> +#ifdef CONFIG_USER_NS_FSID
> +extern const struct seq_operations proc_fsuid_seq_operations;
> +extern const struct seq_operations proc_fsgid_seq_operations;
> +extern ssize_t proc_fsuid_map_write(struct file *, const char __user *, size_t, loff_t *);
> +extern ssize_t proc_fsgid_map_write(struct file *, const char __user *, size_t, loff_t *);
> +#endif
>  extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
>  extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
>  extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *);
> diff --git a/init/Kconfig b/init/Kconfig
> index cfee56c151f1..d4d0beeba48f 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1111,6 +1111,17 @@ config USER_NS
>  
>  	  If unsure, say N.
>  
> +config USER_NS_FSID
> +	bool "User namespace fsid mappings"
> +	depends on USER_NS
> +	default n
> +	help
> +	  This allows containers to alter their filesystem id mappings.
> +	  With this containers with different id mappings can still share
> +	  the same filesystem.
> +
> +	  If unsure, say N.
> +
>  config PID_NS
>  	bool "PID Namespaces"
>  	default y
> diff --git a/kernel/user.c b/kernel/user.c
> index 5235d7f49982..2ccaea9b810b 100644
> --- a/kernel/user.c
> +++ b/kernel/user.c
> @@ -55,6 +55,28 @@ struct user_namespace init_user_ns = {
>  			},
>  		},
>  	},
> +#ifdef CONFIG_USER_NS_FSID
> +	.fsuid_map = {
> +		.nr_extents = 1,
> +		{
> +			.extent[0] = {
> +				.first = 0,
> +				.lower_first = 0,
> +				.count = 4294967295U,
> +			},
> +		},
> +	},
> +	.fsgid_map = {
> +		.nr_extents = 1,
> +		{
> +			.extent[0] = {
> +				.first = 0,
> +				.lower_first = 0,
> +				.count = 4294967295U,
> +			},
> +		},
> +	},
> +#endif
>  	.count = ATOMIC_INIT(3),
>  	.owner = GLOBAL_ROOT_UID,
>  	.group = GLOBAL_ROOT_GID,
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 8eadadc478f9..cbdf456f95f0 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -191,6 +191,16 @@ static void free_user_ns(struct work_struct *work)
>  			kfree(ns->projid_map.forward);
>  			kfree(ns->projid_map.reverse);
>  		}
> +#ifdef CONFIG_USER_NS_FSID
> +		if (ns->fsgid_map.nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) {
> +			kfree(ns->fsgid_map.forward);
> +			kfree(ns->fsgid_map.reverse);
> +		}
> +		if (ns->fsuid_map.nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) {
> +			kfree(ns->fsuid_map.forward);
> +			kfree(ns->fsuid_map.reverse);
> +		}
> +#endif
>  		retire_userns_sysctls(ns);
>  		key_free_user_ns(ns);
>  		ns_free_inum(&ns->ns);
> @@ -637,6 +647,50 @@ static int projid_m_show(struct seq_file *seq, void *v)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_USER_NS_FSID
> +static int fsuid_m_show(struct seq_file *seq, void *v)
> +{
> +	struct user_namespace *ns = seq->private;
> +	struct uid_gid_extent *extent = v;
> +	struct user_namespace *lower_ns;
> +	uid_t lower;
> +
> +	lower_ns = seq_user_ns(seq);
> +	if ((lower_ns == ns) && lower_ns->parent)
> +		lower_ns = lower_ns->parent;
> +
> +	lower = from_kuid(lower_ns, KUIDT_INIT(extent->lower_first));
> +
> +	seq_printf(seq, "%10u %10u %10u\n",
> +		extent->first,
> +		lower,
> +		extent->count);
> +
> +	return 0;
> +}
> +
> +static int fsgid_m_show(struct seq_file *seq, void *v)
> +{
> +	struct user_namespace *ns = seq->private;
> +	struct uid_gid_extent *extent = v;
> +	struct user_namespace *lower_ns;
> +	gid_t lower;
> +
> +	lower_ns = seq_user_ns(seq);
> +	if ((lower_ns == ns) && lower_ns->parent)
> +		lower_ns = lower_ns->parent;
> +
> +	lower = from_kgid(lower_ns, KGIDT_INIT(extent->lower_first));
> +
> +	seq_printf(seq, "%10u %10u %10u\n",
> +		extent->first,
> +		lower,
> +		extent->count);
> +
> +	return 0;
> +}
> +#endif
> +
>  static void *m_start(struct seq_file *seq, loff_t *ppos,
>  		     struct uid_gid_map *map)
>  {
> @@ -674,6 +728,22 @@ static void *projid_m_start(struct seq_file *seq, loff_t *ppos)
>  	return m_start(seq, ppos, &ns->projid_map);
>  }
>  
> +#ifdef CONFIG_USER_NS_FSID
> +static void *fsuid_m_start(struct seq_file *seq, loff_t *ppos)
> +{
> +	struct user_namespace *ns = seq->private;
> +
> +	return m_start(seq, ppos, &ns->fsuid_map);
> +}
> +
> +static void *fsgid_m_start(struct seq_file *seq, loff_t *ppos)
> +{
> +	struct user_namespace *ns = seq->private;
> +
> +	return m_start(seq, ppos, &ns->fsgid_map);
> +}
> +#endif
> +
>  static void *m_next(struct seq_file *seq, void *v, loff_t *pos)
>  {
>  	(*pos)++;
> @@ -706,6 +776,22 @@ const struct seq_operations proc_projid_seq_operations = {
>  	.show = projid_m_show,
>  };
>  
> +#ifdef CONFIG_USER_NS_FSID
> +const struct seq_operations proc_fsuid_seq_operations = {
> +	.start = fsuid_m_start,
> +	.stop = m_stop,
> +	.next = m_next,
> +	.show = fsuid_m_show,
> +};
> +
> +const struct seq_operations proc_fsgid_seq_operations = {
> +	.start = fsgid_m_start,
> +	.stop = m_stop,
> +	.next = m_next,
> +	.show = fsgid_m_show,
> +};
> +#endif
> +
>  static bool mappings_overlap(struct uid_gid_map *new_map,
>  			     struct uid_gid_extent *extent)
>  {
> @@ -1081,6 +1167,42 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf,
>  			 &ns->projid_map, &ns->parent->projid_map);
>  }
>  
> +#ifdef CONFIG_USER_NS_FSID
> +ssize_t proc_fsuid_map_write(struct file *file, const char __user *buf,
> +			     size_t size, loff_t *ppos)
> +{
> +	struct seq_file *seq = file->private_data;
> +	struct user_namespace *ns = seq->private;
> +	struct user_namespace *seq_ns = seq_user_ns(seq);
> +
> +	if (!ns->parent)
> +		return -EPERM;
> +
> +	if ((seq_ns != ns) && (seq_ns != ns->parent))
> +		return -EPERM;
> +
> +	return map_write(file, buf, size, ppos, CAP_SETUID, &ns->fsuid_map,
> +			 &ns->parent->fsuid_map);
> +}
> +
> +ssize_t proc_fsgid_map_write(struct file *file, const char __user *buf,
> +			     size_t size, loff_t *ppos)
> +{
> +	struct seq_file *seq = file->private_data;
> +	struct user_namespace *ns = seq->private;
> +	struct user_namespace *seq_ns = seq_user_ns(seq);
> +
> +	if (!ns->parent)
> +		return -EPERM;
> +
> +	if ((seq_ns != ns) && (seq_ns != ns->parent))
> +		return -EPERM;
> +
> +	return map_write(file, buf, size, ppos, CAP_SETGID, &ns->fsgid_map,
> +			 &ns->parent->fsgid_map);
> +}
> +#endif
> +
>  static bool new_idmap_permitted(const struct file *file,
>  				struct user_namespace *ns, int cap_setid,
>  				struct uid_gid_map *new_map)
> -- 
> 2.25.0

  reply	other threads:[~2020-02-19  2:33 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-18 14:33 [PATCH v3 00/25] user_namespace: introduce fsid mappings Christian Brauner
2020-02-18 14:33 ` [PATCH v3 01/25] user_namespace: introduce fsid mappings infrastructure Christian Brauner
2020-02-19  2:33   ` Serge E. Hallyn [this message]
2020-02-18 14:33 ` [PATCH v3 02/25] proc: add /proc/<pid>/fsuid_map Christian Brauner
2020-02-19  2:33   ` Serge E. Hallyn
2020-02-18 14:33 ` [PATCH v3 03/25] proc: add /proc/<pid>/fsgid_map Christian Brauner
2020-02-19  2:33   ` Serge E. Hallyn
2020-02-18 14:33 ` [PATCH v3 04/25] fsuidgid: add fsid mapping helpers Christian Brauner
2020-02-18 14:33 ` [PATCH v3 05/25] user_namespace: refactor map_write() Christian Brauner
2020-02-19  2:35   ` Serge E. Hallyn
2020-02-18 14:33 ` [PATCH v3 06/25] user_namespace: make map_write() support fsid mappings Christian Brauner
2020-02-19 16:18   ` Jann Horn
2020-02-18 14:33 ` [PATCH v3 07/25] proc: task_state(): use from_kfs{g,u}id_munged Christian Brauner
2020-02-19  2:36   ` Serge E. Hallyn
2020-02-18 14:33 ` [PATCH v3 08/25] cred: add kfs{g,u}id Christian Brauner
2020-02-18 14:33 ` [PATCH v3 09/25] fs: add is_userns_visible() helper Christian Brauner
2020-02-19  2:42   ` Serge E. Hallyn
2020-02-19 12:06     ` Christian Brauner
2020-02-19 17:18       ` Andy Lutomirski
2020-02-20 14:26         ` Serge E. Hallyn
2020-02-18 14:33 ` [PATCH v3 10/25] namei: may_{o_}create(): handle fsid mappings Christian Brauner
2020-02-18 14:33 ` [PATCH v3 11/25] inode: inode_owner_or_capable(): " Christian Brauner
2020-02-18 22:25   ` Christoph Hellwig
2020-02-19 12:29     ` Christian Brauner
2020-02-18 14:33 ` [PATCH v3 12/25] capability: privileged_wrt_inode_uidgid(): " Christian Brauner
2020-02-18 14:33 ` [PATCH v3 13/25] stat: " Christian Brauner
2020-02-18 14:34 ` [PATCH v3 14/25] open: " Christian Brauner
2020-02-18 14:34 ` [PATCH v3 15/25] posix_acl: " Christian Brauner
2020-02-18 22:26   ` Christoph Hellwig
2020-02-19 12:56     ` Christian Brauner
2020-02-18 14:34 ` [PATCH v3 16/25] attr: notify_change(): " Christian Brauner
2020-02-18 14:34 ` [PATCH v3 17/25] commoncap: cap_bprm_set_creds(): " Christian Brauner
2020-02-18 14:34 ` [PATCH v3 18/25] commoncap: cap_task_fix_setuid(): " Christian Brauner
2020-02-18 14:34 ` [PATCH v3 19/25] commoncap: handle fsid mappings with vfs caps Christian Brauner
2020-02-19 15:53   ` Jann Horn
2020-02-18 14:34 ` [PATCH v3 20/25] exec: bprm_fill_uid(): handle fsid mappings Christian Brauner
2020-02-18 14:34 ` [PATCH v3 21/25] ptrace: adapt ptrace_may_access() to always uses unmapped fsids Christian Brauner
2020-02-18 14:34 ` [PATCH v3 22/25] devpts: handle fsid mappings Christian Brauner
2020-02-18 14:34 ` [PATCH v3 23/25] keys: " Christian Brauner
2020-02-18 14:34 ` [PATCH v3 24/25] sys: handle fsid mappings in set*id() calls Christian Brauner
2020-02-19 15:42   ` Jann Horn
2020-02-18 14:34 ` [PATCH v3 25/25] selftests: add simple fsid mapping selftests Christian Brauner
2020-02-18 23:50 ` [PATCH v3 00/25] user_namespace: introduce fsid mappings James Bottomley
2020-02-19 12:27   ` Christian Brauner
2020-02-19 15:36     ` James Bottomley
2020-02-19 15:33 ` Jann Horn
2020-02-19 19:35 ` Serge E. Hallyn
2020-02-19 21:48   ` Serge E. Hallyn
2020-02-19 21:56     ` Tycho Andersen
2020-02-27 19:33 ` Josef Bacik
2020-03-02 14:34   ` Serge E. Hallyn

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=20200219023326.GA19144@mail.hallyn.com \
    --to=serge@hallyn.com \
    --cc=adobriyan@gmail.com \
    --cc=christian.brauner@ubuntu.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=corbet@lwn.net \
    --cc=cyphar@cyphar.com \
    --cc=ebiederm@xmission.com \
    --cc=estesp@gmail.com \
    --cc=jannh@google.com \
    --cc=jmorris@namei.org \
    --cc=keescook@chromium.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=seth.forshee@canonical.com \
    --cc=smbarber@chromium.org \
    --cc=stgraber@ubuntu.com \
    --cc=viro@zeniv.linux.org.uk \
    /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.