All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Serge E. Hallyn" <serge@hallyn.com>
To: Giuseppe Scrivano <gscrivan@redhat.com>
Cc: linux-kernel@vger.kernel.org, serge@hallyn.com,
	dwalsh@redhat.com, christian.brauner@ubuntu.com,
	ebiederm@xmission.com
Subject: Re: [RFC PATCH 2/3] getgroups: hide unknown groups
Date: Fri, 14 May 2021 20:21:21 -0500	[thread overview]
Message-ID: <20210515012121.GA2325@mail.hallyn.com> (raw)
In-Reply-To: <20210510130011.1441834-3-gscrivan@redhat.com>

On Mon, May 10, 2021 at 03:00:10PM +0200, Giuseppe Scrivano wrote:
> do not copy to userspace the groups that are not known in the
> namespace.
> 
> Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

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

> ---
>  kernel/groups.c | 40 +++++++++++++++++++--------------------
>  kernel/uid16.c  | 50 ++++++++++++++++++++++++-------------------------
>  2 files changed, 44 insertions(+), 46 deletions(-)
> 
> diff --git a/kernel/groups.c b/kernel/groups.c
> index f0c3b49da19e..97fa9faa7813 100644
> --- a/kernel/groups.c
> +++ b/kernel/groups.c
> @@ -35,19 +35,30 @@ EXPORT_SYMBOL(groups_free);
>  
>  /* export the group_info to a user-space array */
>  static int groups_to_user(gid_t __user *grouplist,
> -			  const struct group_info *group_info)
> +			  const struct group_info *group_info,
> +			  int gidsetsize)
>  {
>  	struct user_namespace *user_ns = current_user_ns();
> -	int i;
>  	unsigned int count = group_info->ngroups;
> +	int i, ngroups = 0;
>  
>  	for (i = 0; i < count; i++) {
>  		gid_t gid;
> -		gid = from_kgid_munged(user_ns, group_info->gid[i]);
> -		if (put_user(gid, grouplist+i))
> -			return -EFAULT;
> +		gid = from_kgid(user_ns, group_info->gid[i]);
> +		if (gid == (gid_t)-1) {
> +			if (user_ns->flags & USERNS_SETGROUPS_SHADOW)
> +				continue;
> +			gid = overflowgid;
> +		}
> +		if (gidsetsize) {
> +			if (ngroups == gidsetsize)
> +				return -EINVAL;
> +			if (put_user(gid, grouplist + ngroups))
> +				return -EFAULT;
> +		}
> +		ngroups++;
>  	}
> -	return 0;
> +	return ngroups;
>  }
>  
>  /* fill a group_info from a user-space array - it must be allocated already */
> @@ -146,26 +157,13 @@ EXPORT_SYMBOL(set_current_groups);
>  
>  SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist)
>  {
> +	/* no need to grab task_lock here; it cannot change */
>  	const struct cred *cred = current_cred();
> -	int i;
>  
>  	if (gidsetsize < 0)
>  		return -EINVAL;
>  
> -	/* no need to grab task_lock here; it cannot change */
> -	i = cred->group_info->ngroups;
> -	if (gidsetsize) {
> -		if (i > gidsetsize) {
> -			i = -EINVAL;
> -			goto out;
> -		}
> -		if (groups_to_user(grouplist, cred->group_info)) {
> -			i = -EFAULT;
> -			goto out;
> -		}
> -	}
> -out:
> -	return i;
> +	return groups_to_user(grouplist, cred->group_info, gidsetsize);
>  }
>  
>  bool may_setgroups(struct group_info **shadowed_groups)
> diff --git a/kernel/uid16.c b/kernel/uid16.c
> index cb1110f083ce..6f2dc793b5f8 100644
> --- a/kernel/uid16.c
> +++ b/kernel/uid16.c
> @@ -112,21 +112,33 @@ SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid)
>  }
>  
>  static int groups16_to_user(old_gid_t __user *grouplist,
> -    struct group_info *group_info)
> +			    struct group_info *group_info,
> +			    int gidsetsize)
>  {
>  	struct user_namespace *user_ns = current_user_ns();
> -	int i;
> -	old_gid_t group;
> -	kgid_t kgid;
> +	unsigned int count = group_info->ngroups;
> +	int i, ngroups = 0;
>  
> -	for (i = 0; i < group_info->ngroups; i++) {
> -		kgid = group_info->gid[i];
> -		group = high2lowgid(from_kgid_munged(user_ns, kgid));
> -		if (put_user(group, grouplist+i))
> -			return -EFAULT;
> +	for (i = 0; i < count; i++) {
> +		gid_t gid;
> +		old_gid_t group;
> +
> +		gid = from_kgid(user_ns, group_info->gid[i]);
> +		if (gid == (gid_t)-1) {
> +			if (user_ns->flags & USERNS_SETGROUPS_SHADOW)
> +				continue;
> +			gid = overflowgid;
> +		}
> +		group = high2lowgid(gid);
> +		if (gidsetsize) {
> +			if (ngroups == gidsetsize)
> +				return -EINVAL;
> +			if (put_user(group, grouplist + ngroups))
> +				return -EFAULT;
> +		}
> +		ngroups++;
>  	}
> -
> -	return 0;
> +	return ngroups;
>  }
>  
>  static int groups16_from_user(struct group_info *group_info,
> @@ -153,25 +165,13 @@ static int groups16_from_user(struct group_info *group_info,
>  
>  SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
>  {
> +	/* no need to grab task_lock here; it cannot change */
>  	const struct cred *cred = current_cred();
> -	int i;
>  
>  	if (gidsetsize < 0)
>  		return -EINVAL;
>  
> -	i = cred->group_info->ngroups;
> -	if (gidsetsize) {
> -		if (i > gidsetsize) {
> -			i = -EINVAL;
> -			goto out;
> -		}
> -		if (groups16_to_user(grouplist, cred->group_info)) {
> -			i = -EFAULT;
> -			goto out;
> -		}
> -	}
> -out:
> -	return i;
> +	return groups16_to_user(grouplist, cred->group_info, gidsetsize);
>  }
>  
>  SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
> -- 
> 2.31.1

  reply	other threads:[~2021-05-15  1:21 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-10 13:00 [RFC PATCH 0/3] new mode 'shadow' for /proc/PID/setgroups Giuseppe Scrivano
2021-05-10 13:00 ` [RFC PATCH 1/3] setgroups: " Giuseppe Scrivano
2021-05-15  1:51   ` Serge E. Hallyn
2021-05-17 13:30     ` Giuseppe Scrivano
2021-05-17 14:33       ` Christian Brauner
2021-05-17 16:17         ` Serge E. Hallyn
2021-05-18  9:32           ` Christian Brauner
2021-05-17 19:00         ` Giuseppe Scrivano
2021-05-18  9:16           ` Christian Brauner
2021-05-21 14:03         ` Snaipe
2021-05-17 16:08       ` Serge E. Hallyn
2021-05-10 13:00 ` [RFC PATCH 2/3] getgroups: hide unknown groups Giuseppe Scrivano
2021-05-15  1:21   ` Serge E. Hallyn [this message]
2021-05-10 13:00 ` [RFC PATCH 3/3] proc: hide unknown groups in status Giuseppe Scrivano
2021-05-15  1:24   ` Serge E. Hallyn
2021-05-10 16:02 ` [RFC PATCH 0/3] new mode 'shadow' for /proc/PID/setgroups Snaipe
2021-05-21 15:16 ` Eric W. Biederman
2021-05-24 13:41   ` Giuseppe Scrivano

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=20210515012121.GA2325@mail.hallyn.com \
    --to=serge@hallyn.com \
    --cc=christian.brauner@ubuntu.com \
    --cc=dwalsh@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=gscrivan@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /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.