]> sourceware.org Git - glibc.git/commitdiff
[BZ #13761]
authorJeff Law <law@redhat.com>
Thu, 29 Mar 2012 15:56:27 +0000 (09:56 -0600)
committerJeff Law <law@redhat.com>
Thu, 29 Mar 2012 15:56:27 +0000 (09:56 -0600)
* nis/nss_compat/compat-initgroups.c (getgrent_next_nss,
_nss_compat_initgroups_dyn): Fall back to malloc/free for
large group memberships.

ChangeLog
NEWS
nis/nss_compat/compat-initgroups.c

index 23b72905f5e473a3f21a512738310c43ac4cf054..165a178076ef21f72c61a44cf5f2690e4a13ddb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-03-28  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+       [BZ #13761]
+       * nis/nss_compat/compat-initgroups.c (getgrent_next_nss,
+       _nss_compat_initgroups_dyn): Fall back to malloc/free
+       for large group memberships.
+
 2012-03-28  David S. Miller  <davem@davemloft.net>
 
        * sysdeps/sparc/sparc32/memcpy.S: Implement mempcpy using a stub
diff --git a/NEWS b/NEWS
index ec8ecdb45d03a9b0d9e01709a479c7d43f7813a4..612acc85819ba1151e7e920c2e9c72673e75ee9c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,9 +16,9 @@ Version 2.16
   11494, 12047, 13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531,
   13532, 13533, 13547, 13551, 13552, 13553, 13555, 13559, 13566, 13583,
   13618, 13637, 13656, 13658, 13673, 13695, 13704, 13706, 13726, 13738,
-  13760, 13786, 13792, 13806, 13824, 13840, 13841, 13844, 13846, 13851,
-  13852, 13854, 13871, 13879, 13883, 13892, 13910, 13911, 13912, 13913,
-  13915, 13916, 13917, 13918, 13919, 13920, 13921
+  13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841, 13844, 13846,
+  13851, 13852, 13854, 13871, 13879, 13883, 13892, 13910, 13911, 13912,
+  13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921
 
 * ISO C11 support:
 
index a70d66df8b8cfc648e3f15746758e696ee0728d1..4aa23fda189f7e8781cf02362bc95b7e4213c145 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2004,2006,2007,2009,2010 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2004,2006,2007,2009,2010,2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
 
@@ -296,6 +296,8 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
       if (nss_initgroups_dyn (user, group, &mystart, &mysize, &mygroups,
                              limit, errnop) == NSS_STATUS_SUCCESS)
        {
+         status = NSS_STATUS_NOTFOUND;
+
          /* If there is no blacklist we can trust the underlying
             initgroups implementation.  */
          if (ent->blacklist.current <= 1)
@@ -308,6 +310,7 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
                 overwrite the pointer with one to a bigger buffer.  */
              char *tmpbuf = buffer;
              size_t tmplen = buflen;
+             bool use_malloc = false;
 
              for (int i = 0; i < mystart; i++)
                {
@@ -315,21 +318,36 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
                                                   tmpbuf, tmplen, errnop))
                         == NSS_STATUS_TRYAGAIN
                         && *errnop == ERANGE)
-                   if (tmpbuf == buffer)
-                     {
-                       tmplen *= 2;
-                       tmpbuf = __alloca (tmplen);
-                     }
-                   else
-                     tmpbuf = extend_alloca (tmpbuf, tmplen, 2 * tmplen);
+                    {
+                      if (__libc_use_alloca (tmplen * 2))
+                        {
+                          if (tmpbuf == buffer)
+                            {
+                              tmplen *= 2;
+                              tmpbuf = __alloca (tmplen);
+                            }
+                          else
+                            tmpbuf = extend_alloca (tmpbuf, tmplen, tmplen * 2);
+                        }
+                      else
+                        {
+                          tmplen *= 2;
+                          char *newbuf = realloc (use_malloc ? tmpbuf : NULL, tmplen);
+
+                          if (newbuf == NULL)
+                            {
+                              status = NSS_STATUS_TRYAGAIN;
+                             goto done;
+                            }
+                          use_malloc = true;
+                          tmpbuf = newbuf;
+                        }
+                    }
 
                  if (__builtin_expect  (status != NSS_STATUS_NOTFOUND, 1))
                    {
                      if (__builtin_expect  (status != NSS_STATUS_SUCCESS, 0))
-                       {
-                         free (mygroups);
-                         return status;
-                       }
+                       goto done;
 
                      if (!in_blacklist (grpbuf.gr_name,
                                         strlen (grpbuf.gr_name), ent)
@@ -347,11 +365,17 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
                        }
                    }
                }
+
+             status = NSS_STATUS_NOTFOUND;
+
+ done:
+             if (use_malloc)
+               free (tmpbuf);
            }
 
          free (mygroups);
 
-         return NSS_STATUS_NOTFOUND;
+         return status;
        }
 
       free (mygroups);
@@ -508,6 +532,7 @@ _nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
   char *tmpbuf;
   enum nss_status status;
   ent_t intern = { true, false, false, NULL, {NULL, 0, 0} };
+  bool use_malloc = false;
 
   status = internal_setgrent (&intern);
   if (status != NSS_STATUS_SUCCESS)
@@ -521,13 +546,32 @@ _nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
                                            user, group, start, size,
                                            groupsp, limit, errnop))
             == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
-       tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
+        if (__libc_use_alloca (buflen * 2))
+          tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
+        else
+          {
+            buflen *= 2;
+            char *newbuf = realloc (use_malloc ? tmpbuf : NULL, buflen);
+            if (newbuf == NULL)
+              {
+                status = NSS_STATUS_TRYAGAIN;
+                goto done;
+              }
+            use_malloc = true;
+            tmpbuf = newbuf;
+          }
     }
   while (status == NSS_STATUS_SUCCESS);
 
+  status = NSS_STATUS_SUCCESS;
+
+ done:
+  if (use_malloc)
+    free (tmpbuf);
+
   internal_endgrent (&intern);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 
This page took 0.049003 seconds and 5 git commands to generate.