]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
id: fix infinite loop on some systems
authorPádraig Brady <P@draigBrady.com>
Wed, 8 Apr 2009 09:43:15 +0000 (10:43 +0100)
committerPádraig Brady <P@draigBrady.com>
Thu, 9 Apr 2009 13:07:29 +0000 (14:07 +0100)
Steven Parkes reported that `id -G $USER` went into an infinite loop
on Darwin systems for users in more than 10 groups:
http://bugs.gentoo.org/show_bug.cgi?id=264007
* gl/lib/mgetgroups.c (mgetgroups): Work around buggy getgrouplist
implementations that don't update the required size correctly,
by doubling the result buffer and retrying. Also return the
parameter updated by getgrouplist rather than its return value,
as the documentation doesn't actually state the number of groups
stored is returned by getgrouplist.
* tests/misc/id-groups: Add test to exercise this logic
* tests/Makefile.am: Reference new test
* NEWS: Mention the fix
* THANKS: Update

NEWS
THANKS
gl/lib/mgetgroups.c
tests/Makefile.am
tests/misc/id-groups [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index de1db443751115d9ff6b6cdfd5e9ffbee4281e4b..a116b646ca7ef4dbe3297a0267be5c5b1c4abda8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,14 @@ GNU coreutils NEWS                                    -*- outline -*-
   default should proceed at the speed of the disk.  Previously /dev/urandom
   was used if available, which is relatively slow on GNU/Linux systems.
 
+** Portability
+
+  `id -G $USER` now works correctly even on Darwin and NetBSD. Previously it
+  would either truncate the group list to 10, or go into an infinite loop,
+  due to their non-standard getgroups implementations.
+  [truncation introduced in coreutils-6.11]
+  [infinite loop introduced in coreutils-7.1]
+
 * Noteworthy changes in release 7.2 (2009-03-31) [stable]
 
 ** New features
diff --git a/THANKS b/THANKS
index 6a918a4297aea77dab29cea3b3028bfcb45c5f56..fe523fe12b3dcb62a769825c209aea6f390abe5a 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -525,6 +525,7 @@ Steve McIntyre                      steve@einval.com
 Steve Ward                          planet36@gmail.com
 Steven G. Johnson                   stevenj@alum.mit.edu
 Steven Mocking                      ufo@quicknet.nl
+Steven Parkes                       smparkes@smparkes.net
 Steven Schveighoffer                schveiguy@yahoo.com
 Steven P Watson                     steven@magelico.net
 Stuart Kemp                         skemp@peter.bmc.com
index e697013ef0ece1f73dc3a81af6ead82f0ccfb110..736dd87f38ff213fa33e3336c10a999d3f4a5f0a 100644 (file)
@@ -81,10 +81,16 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
       while (1)
        {
          GETGROUPS_T *h;
+         int last_n_groups = max_n_groups;
 
          /* getgrouplist updates max_n_groups to num required.  */
          ng = getgrouplist (username, gid, g, &max_n_groups);
 
+         /* Some systems (like Darwin) have a bug where they
+            never increase max_n_groups.  */
+         if (ng < 0 && last_n_groups == max_n_groups)
+           max_n_groups *= 2;
+
          if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
            {
              int saved_errno = errno;
@@ -97,7 +103,9 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
          if (0 <= ng)
            {
              *groups = g;
-             return ng;
+             /* On success some systems just return 0 from getgrouplist,
+                so return max_n_groups rather than ng.  */
+             return max_n_groups;
            }
        }
     }
index 07f34ec4500e848cf68f9d1df366e7966372fa4d..8ce6a2118f94438878119b5e488041e849471f85 100644 (file)
@@ -171,6 +171,7 @@ TESTS =                                             \
   misc/head-c                                  \
   misc/head-pos                                        \
   misc/id-context                              \
+  misc/id-groups                               \
   misc/md5sum                                  \
   misc/md5sum-newline                          \
   misc/mknod                                   \
diff --git a/tests/misc/id-groups b/tests/misc/id-groups
new file mode 100755 (executable)
index 0000000..dc0f54c
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Ensure that "id" outputs groups for a user
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  id --version
+fi
+
+. $srcdir/test-lib.sh
+
+fail=0
+id -G $(id -nu) || fail=1
+
+Exit $fail