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 05/25] user_namespace: refactor map_write()
Date: Tue, 18 Feb 2020 20:35:52 -0600	[thread overview]
Message-ID: <20200219023552.GD19144@mail.hallyn.com> (raw)
In-Reply-To: <20200218143411.2389182-6-christian.brauner@ubuntu.com>

On Tue, Feb 18, 2020 at 03:33:51PM +0100, Christian Brauner wrote:
> Refactor map_write() to prepare for adding fsid mappings support. This mainly
> factors out various open-coded parts into helpers that can be reused in the
> follow up patch.
> 
> Cc: Jann Horn <jannh@google.com>
> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>

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

> ---
> /* v2 */
> patch not present
> 
> /* v3 */
> patch added
> - Jann Horn <jannh@google.com>:
>   - Split changes to map_write() to implement fsid mappings into three separate
>     patches: basic fsid helpers, preparatory changes to map_write(), actual
>     fsid mapping support in map_write().
> ---
>  kernel/user_namespace.c | 117 +++++++++++++++++++++++++---------------
>  1 file changed, 74 insertions(+), 43 deletions(-)
> 
> diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> index 2cfd1e519cc4..e91141262bcc 100644
> --- a/kernel/user_namespace.c
> +++ b/kernel/user_namespace.c
> @@ -1038,10 +1038,10 @@ static int cmp_extents_reverse(const void *a, const void *b)
>  }
>  
>  /**
> - * sort_idmaps - Sorts an array of idmap entries.
> + * sort_map - Sorts an array of idmap entries.
>   * Can only be called if number of mappings exceeds UID_GID_MAP_MAX_BASE_EXTENTS.
>   */
> -static int sort_idmaps(struct uid_gid_map *map)
> +static int sort_map(struct uid_gid_map *map)
>  {
>  	if (map->nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
>  		return 0;
> @@ -1064,6 +1064,71 @@ static int sort_idmaps(struct uid_gid_map *map)
>  	return 0;
>  }
>  
> +static int sort_idmaps(struct uid_gid_map *map)
> +{
> +	return sort_map(map);
> +}
> +
> +static int map_from_parent(struct uid_gid_map *new_map,
> +			   struct uid_gid_map *parent_map)
> +{
> +	unsigned idx;
> +
> +	/* Map the lower ids from the parent user namespace to the
> +	 * kernel global id space.
> +	 */
> +	for (idx = 0; idx < new_map->nr_extents; idx++) {
> +		struct uid_gid_extent *e;
> +		u32 lower_first;
> +
> +		if (new_map->nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
> +			e = &new_map->extent[idx];
> +		else
> +			e = &new_map->forward[idx];
> +
> +		lower_first = map_id_range_down(parent_map, e->lower_first, e->count);
> +
> +		/* Fail if we can not map the specified extent to
> +		 * the kernel global id space.
> +		 */
> +		if (lower_first == (u32)-1)
> +			return -EPERM;
> +
> +		e->lower_first = lower_first;
> +	}
> +
> +	return 0;
> +}
> +
> +static int map_into_kids(struct uid_gid_map *id_map,
> +			 struct uid_gid_map *parent_id_map)
> +{
> +	return map_from_parent(id_map, parent_id_map);
> +}
> +
> +static void install_idmaps(struct uid_gid_map *id_map,
> +			   struct uid_gid_map *new_id_map)
> +{
> +	if (new_id_map->nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS) {
> +		memcpy(id_map->extent, new_id_map->extent,
> +		       new_id_map->nr_extents * sizeof(new_id_map->extent[0]));
> +	} else {
> +		id_map->forward = new_id_map->forward;
> +		id_map->reverse = new_id_map->reverse;
> +	}
> +}
> +
> +static void free_idmaps(struct uid_gid_map *new_id_map)
> +{
> +	if (new_id_map->nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) {
> +		kfree(new_id_map->forward);
> +		kfree(new_id_map->reverse);
> +		new_id_map->forward = NULL;
> +		new_id_map->reverse = NULL;
> +		new_id_map->nr_extents = 0;
> +	}
> +}
> +
>  static ssize_t map_write(struct file *file, const char __user *buf,
>  			 size_t count, loff_t *ppos,
>  			 int cap_setid,
> @@ -1073,7 +1138,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
>  	struct seq_file *seq = file->private_data;
>  	struct user_namespace *ns = seq->private;
>  	struct uid_gid_map new_map;
> -	unsigned idx;
>  	struct uid_gid_extent extent;
>  	char *kbuf = NULL, *pos, *next_line;
>  	ssize_t ret;
> @@ -1191,61 +1255,28 @@ static ssize_t map_write(struct file *file, const char __user *buf,
>  	if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
>  		goto out;
>  
> -	ret = -EPERM;
> -	/* Map the lower ids from the parent user namespace to the
> -	 * kernel global id space.
> -	 */
> -	for (idx = 0; idx < new_map.nr_extents; idx++) {
> -		struct uid_gid_extent *e;
> -		u32 lower_first;
> -
> -		if (new_map.nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS)
> -			e = &new_map.extent[idx];
> -		else
> -			e = &new_map.forward[idx];
> -
> -		lower_first = map_id_range_down(parent_map,
> -						e->lower_first,
> -						e->count);
> -
> -		/* Fail if we can not map the specified extent to
> -		 * the kernel global id space.
> -		 */
> -		if (lower_first == (u32) -1)
> -			goto out;
> -
> -		e->lower_first = lower_first;
> -	}
> +	ret = map_into_kids(&new_map, parent_map);
> +	if (ret)
> +		goto out;
>  
>  	/*
>  	 * If we want to use binary search for lookup, this clones the extent
>  	 * array and sorts both copies.
>  	 */
>  	ret = sort_idmaps(&new_map);
> -	if (ret < 0)
> +	if (ret)
>  		goto out;
>  
>  	/* Install the map */
> -	if (new_map.nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS) {
> -		memcpy(map->extent, new_map.extent,
> -		       new_map.nr_extents * sizeof(new_map.extent[0]));
> -	} else {
> -		map->forward = new_map.forward;
> -		map->reverse = new_map.reverse;
> -	}
> +	install_idmaps(map, &new_map);
>  	smp_wmb();
>  	map->nr_extents = new_map.nr_extents;
>  
>  	*ppos = count;
>  	ret = count;
>  out:
> -	if (ret < 0 && new_map.nr_extents > UID_GID_MAP_MAX_BASE_EXTENTS) {
> -		kfree(new_map.forward);
> -		kfree(new_map.reverse);
> -		map->forward = NULL;
> -		map->reverse = NULL;
> -		map->nr_extents = 0;
> -	}
> +	if (ret < 0)
> +		free_idmaps(&new_map);
>  
>  	mutex_unlock(&userns_state_mutex);
>  	kfree(kbuf);
> -- 
> 2.25.0

  reply	other threads:[~2020-02-19  2:35 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
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 [this message]
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=20200219023552.GD19144@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.