bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problem with id when mgetgroups returns no groups.


From: Eric Blake
Subject: Re: Problem with id when mgetgroups returns no groups.
Date: Fri, 4 Dec 2009 15:34:03 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> Thanks for your report.  Indeed, looking at mgetgroups.c, if getgroups
> fails, mgetgroups returns -1 without assigning through *groups (likewise
> if realloc_groupbug fails, but that sets errno to ENOMEM).  I also wonder
> if mgetgroups should be taught to recognize ENOSYS itself, and guarantee a
> zero-length array rather than returning with -1 in that case.

I spotted another problem - id was not handling ENOMEM failures consistently 
(in other words, it didn't go through xalloc_die).

How about this alternative patch, which makes gnulib aware of ENOSYS, and 
changes coreutils to use the more robust interface?


From: Eric Blake <address@hidden>
Date: Fri, 4 Dec 2009 08:26:23 -0700
Subject: [PATCH] mgetgroups: add xgetgroups, and avoid ENOSYS failures

* lib/mgetgroups.h (xgetgroups): New prototype.
* lib/mgetgroups.c (xgetgroups): New wrapper.
(mgetgroups): Handle ENOSYS.
* modules/mgetgroups (Depends-on): Add realloc-posix.
Reported by Scott <scott.gnu.2009 AT scottrix.co.uk>.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog          |    8 ++++++++
 lib/mgetgroups.c   |   27 ++++++++++++++++++++++++---
 lib/mgetgroups.h   |    1 +
 modules/mgetgroups |    1 +
 4 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f913f41..319f3c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-12-04  Eric Blake  <address@hidden>
+
+       mgetgroups: add xgetgroups, and avoid ENOSYS failures
+       * lib/mgetgroups.h (xgetgroups): New prototype.
+       * lib/mgetgroups.c (xgetgroups): New wrapper.
+       (mgetgroups): Handle ENOSYS.
+       * modules/mgetgroups (Depends-on): Add realloc-posix.
+
 2009-11-17  Eric Blake  <address@hidden>

        manywarnings: add more warnings
diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c
index f68e28f..3c5ec8d 100644
--- a/lib/mgetgroups.c
+++ b/lib/mgetgroups.c
@@ -118,10 +118,19 @@ mgetgroups (char const *username, gid_t gid, gid_t 
**groups)
                   ? getugroups (0, NULL, username, gid)
                   : getgroups (0, NULL) + (gid != -1));

-  /* If we failed to count groups with NULL for a buffer,
-     try again with a non-NULL one, just in case.  */
+  /* If we failed to count groups because there is no supplemental
+     group support, then return an array containing just GID.
+     Otherwise, we fail for the same reason.  */
   if (max_n_groups < 0)
-      max_n_groups = 5;
+    {
+      if (errno == ENOSYS && (g = realloc_groupbuf (NULL, 1)))
+        {
+          *groups = g;
+          *g = gid;
+          return gid != -1;
+        }
+      return -1;
+    }

   g = realloc_groupbuf (NULL, max_n_groups);
   if (g == NULL)
@@ -133,6 +142,7 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)

   if (ng < 0)
     {
+      /* Failure is unexpected, but handle it anyway.  */
       int saved_errno = errno;
       free (g);
       errno = saved_errno;
@@ -147,3 +157,14 @@ mgetgroups (char const *username, gid_t gid, gid_t 
**groups)
   *groups = g;
   return ng;
 }
+
+/* Like mgetgroups, but call xalloc_die on allocation failure.  */
+
+int
+xgetgroups (char const *username, gid_t gid, gid_t **groups)
+{
+  int result = mgetgroups (username, gid, groups);
+  if (result == -1 && errno == ENOMEM)
+    xalloc_die ();
+  return result;
+}
diff --git a/lib/mgetgroups.h b/lib/mgetgroups.h
index 909d84c..4868d28 100644
--- a/lib/mgetgroups.h
+++ b/lib/mgetgroups.h
@@ -17,3 +17,4 @@
 #include <sys/types.h>

 int mgetgroups (const char *username, gid_t gid, gid_t **groups);
+int xgetgroups (const char *username, gid_t gid, gid_t **groups);
diff --git a/modules/mgetgroups b/modules/mgetgroups
index 58ef740..45ae412 100644
--- a/modules/mgetgroups
+++ b/modules/mgetgroups
@@ -9,6 +9,7 @@ m4/mgetgroups.m4
 Depends-on:
 getgroups
 getugroups
+realloc-posix
 xalloc

 configure.ac:
-- 
1.6.4.2




From: Eric Blake <address@hidden>
Date: Fri, 4 Dec 2009 08:06:55 -0700
Subject: [PATCH] id: handle systems without getgroups support

If getgroups failed with ENOSYS, mgetgroups would unnecessarily
fail, and that provoked id into freeing an uninitialized pointer.
Meanwhile, we were not using xalloc_die properly.  Both issues
are better solved in gnulib, by introducing xgetgroups; this
patch uses the new interface.

* gnulib: Update, for mgetgroups improvments.
* src/id.c (print_full_info): Adjust caller to die on allocation
failure, and no longer worry about ENOSYS.
* src/group-list.c (print_group_list): Likewise.
* src/setuidgid.c (main): Likewise.
---
 gnulib           |    2 +-
 src/group-list.c |    4 ++--
 src/id.c         |    4 ++--
 src/setuidgid.c  |    2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gnulib b/gnulib
index cdfe647..c5588be 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit cdfe647f8d29540cdfe90cef0fa568c5d2fd4481
+Subproject commit 64a72bbf6ed20208d633b9e9d849000aee279a01
diff --git a/src/group-list.c b/src/group-list.c
index 1fadd0c..a4b1f6d 100644
--- a/src/group-list.c
+++ b/src/group-list.c
@@ -58,9 +58,9 @@ print_group_list (const char *username,
     gid_t *groups;
     int i;

-    int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
+    int n_groups = xgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
                                &groups);
-    if (n_groups < 0 && errno != ENOSYS)
+    if (n_groups < 0)
       {
         if (username)
           {
diff --git a/src/id.c b/src/id.c
index 9a00f5c..96d8e96 100644
--- a/src/id.c
+++ b/src/id.c
@@ -296,9 +296,9 @@ print_full_info (const char *username)
     gid_t *groups;
     int i;

-    int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
+    int n_groups = xgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
                                &groups);
-    if (n_groups < 0 && errno != ENOSYS)
+    if (n_groups < 0)
       {
         if (username)
           {
diff --git a/src/setuidgid.c b/src/setuidgid.c
index 0adac21..2710bc9 100644
--- a/src/setuidgid.c
+++ b/src/setuidgid.c
@@ -179,7 +179,7 @@ main (int argc, char **argv)
 #if HAVE_SETGROUPS
     if (n_gids == 0)
       {
-        int n = mgetgroups (pwd->pw_name, pwd->pw_gid, &gids);
+        int n = xgetgroups (pwd->pw_name, pwd->pw_gid, &gids);
         if (n <= 0)
           error (EXIT_FAILURE, errno, _("failed to get groups for user %s"),
                  quote (pwd->pw_name));
-- 
1.6.4.2








reply via email to

[Prev in Thread] Current Thread [Next in Thread]