[libvirt] [PATCH v3 4/4] util: Make failure to get supplementary group list for a uid non-fatal

John Ferlan jferlan at redhat.com
Mon Jun 20 12:10:10 UTC 2016



On 06/17/2016 09:44 AM, Peter Krempa wrote:
> Since introduction of the DAC security driver we've documented that
> seclabels with a leading + can be used with numerical uid. This would
> not work though with the rest of libvirt if the uid was not actually
> used in the system as we'd fail when trying to get a list of
> supplementary groups for the given uid. Since a uid without entry in
> /etc/passwd (or other user database) will not have any supplementary
> groups we can treat the failure to obtain them as such.
> 
> This patch modifies virGetGroupList to not report the error for missing
> users and makes it return an empty list or just the group specified in
> @gid.
> 
> All callers will grand less permissions in case of failure and thus this
> change is safe.

"grand less"?  did you mean "gain less"?


ACK series (just typed out loud below)

John
> ---
>  src/util/virutil.c | 31 ++++++++++++++++---------------
>  1 file changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/src/util/virutil.c b/src/util/virutil.c
> index 392091b..60da17b 100644
> --- a/src/util/virutil.c
> +++ b/src/util/virutil.c
> @@ -1120,29 +1120,30 @@ virGetGroupID(const char *group, gid_t *gid)
> 
>  /* Compute the list of primary and supplementary groups associated
>   * with @uid, and including @gid in the list (unless it is -1),
> - * storing a malloc'd result into @list. Return the size of the list
> - * on success, or -1 on failure with error reported and errno set. May
> - * not be called between fork and exec. */
> + * storing a malloc'd result into @list. If uid is -1 or doesn't exist in the
> + * system database querying of the supplementary groups is skipped.
> + *
> + * Returns the size of the list on success, or -1 on failure with error
> + * reported and errno set. May not be called between fork and exec.
> + * */
>  int
>  virGetGroupList(uid_t uid, gid_t gid, gid_t **list)
>  {
> -    int ret = -1;
> +    int ret = 0;
>      char *user = NULL;
>      gid_t primary;
> 
>      *list = NULL;
> -    if (uid == (uid_t)-1)
> -        return 0;
> 
> -    if (virGetUserEnt(uid, &user, &primary, NULL, NULL, false) < 0)
> -        return -1;
> -
> -    ret = mgetgroups(user, primary, list);
> -    if (ret < 0) {
> -        sa_assert(!*list);
> -        virReportSystemError(errno,
> -                             _("cannot get group list for '%s'"), user);
> -        goto cleanup;
> +    /* invalid users have no supplementary groups */
> +    if (uid != (uid_t)-1 &&
> +        virGetUserEnt(uid, &user, &primary, NULL, NULL, true) >= 0) {
> +        if ((ret = mgetgroups(user, primary, list)) < 0) {
> +            virReportSystemError(errno,
> +                                 _("cannot get group list for '%s'"), user);
> +            ret = -1;
> +            goto cleanup;
> +        }
>      }

Playing the "what if" game here.  If for some reason uid == -1 OR
virGetUserEnt fails, then

gid - still to be determined
ret = 0

> 
>      if (gid != (gid_t)-1) {
> 

If we enter this "if", then the for loop will exit immediately and the
VIR_APPEND_ELEMENT will append that gid onto *list which is IIRC what we
want. Then ret will be set to 1 (i) and we return. Otherwise if gid ==
-1, then we return 0, which is still fine.




More information about the libvir-list mailing list