On Thu, Nov 30 2017, Thiago Rafael Becker wrote:

> The responsibility for calling groups_sort is now on the caller
> of set_groups.
>
> Signed-off-by: Thiago Rafael Becker <thiago.bec...@gmail.com>
> ---
>  kernel/groups.c           | 1 +
>  kernel/uid16.c            | 1 +
>  net/sunrpc/svcauth_unix.c | 7 +++++++
>  3 files changed, 9 insertions(+)
>
> diff --git a/kernel/groups.c b/kernel/groups.c
> index 4c9c9ed..17073a9 100644
> --- a/kernel/groups.c
> +++ b/kernel/groups.c
> @@ -208,6 +208,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user 
> *, grouplist)
>               return retval;
>       }
>  
> +     groups_sort(group_info);
>       retval = set_current_groups(group_info);
>       put_group_info(group_info);
>  
> diff --git a/kernel/uid16.c b/kernel/uid16.c
> index ce74a49..ef1da2a 100644
> --- a/kernel/uid16.c
> +++ b/kernel/uid16.c
> @@ -192,6 +192,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t 
> __user *, grouplist)
>               return retval;
>       }
>  
> +     groups_sort(group_info);
>       retval = set_current_groups(group_info);
>       put_group_info(group_info);
>  
> diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
> index f81eaa8..91e3d34 100644
> --- a/net/sunrpc/svcauth_unix.c
> +++ b/net/sunrpc/svcauth_unix.c
> @@ -20,6 +20,7 @@
>  
>  
>  #include "netns.h"
> +void groups_sort(struct group_info *group_info);
>  
>  /*
>   * AUTHUNIX and AUTHNULL credentials are both handled here.
> @@ -520,6 +521,12 @@ static int unix_gid_parse(struct cache_detail *cd,
>               ug.gi->gid[i] = kgid;
>       }
>  
> +     /* Sort the groups before inserting this entry
> +      * into the cache to avoid future corrutpions
> +      * by multiple simultaneous attempts to sort this
> +      * entry.
> +      */
> +     groups_sort(ug.gi);
>       ugp = unix_gid_lookup(cd, uid);
>       if (ugp) {
>               struct cache_head *ch;


I think you need to add groups_sort() in a few more places.
Almost anywhere that calls groups_alloc() should be considered.
net/sunrpc/svcauth_unix.c, net/sunrpc/auth_gss/svcauth_gss.c,
fs/nfsd/auth.c definitely need it.

I wonder if there is a more robust way to fix this.
Maybe:
  groups_alloc() could initialize ->usage to -1
  groups_sort() to require it be -1, and change it to 1
  get_group_info() complains if ->usage is -1 ???

or something.
Maybe it could be done with types.
'struct group_info' could be declared with ngroups and
gid[] as const.
'struct group_info_unsorted' could be the same structure but
without the 'const'.
Then groups_sort() takes a 'struct group_info_unsorted *' and returns
a 'struct group_info *'...

Thanks,
NeilBrown

Attachment: signature.asc
Description: PGP signature

Reply via email to