Blame SOURCES/glibc-rh788959.patch

b9ba6d
diff -pruN glibc-2.12-2-gc4ccff1/nis/nss_compat/compat-initgroups.c glibc-2.12-2-gc4ccff1.patched/nis/nss_compat/compat-initgroups.c
b9ba6d
--- glibc-2.12-2-gc4ccff1/nis/nss_compat/compat-initgroups.c	2010-05-04 16:57:23.000000000 +0530
b9ba6d
+++ glibc-2.12-2-gc4ccff1.patched/nis/nss_compat/compat-initgroups.c	2012-02-21 11:11:19.877008465 +0530
b9ba6d
@@ -297,6 +297,8 @@ getgrent_next_nss (ent_t *ent, char *buf
b9ba6d
       if (nss_initgroups_dyn (user, group, &mystart, &mysize, &mygroups,
b9ba6d
 			      limit, errnop) == NSS_STATUS_SUCCESS)
b9ba6d
 	{
b9ba6d
+	  status = NSS_STATUS_NOTFOUND;
b9ba6d
+
b9ba6d
 	  /* If there is no blacklist we can trust the underlying
b9ba6d
 	     initgroups implementation.  */
b9ba6d
 	  if (ent->blacklist.current <= 1)
b9ba6d
@@ -309,6 +311,7 @@ getgrent_next_nss (ent_t *ent, char *buf
b9ba6d
 		 overwrite the pointer with one to a bigger buffer.  */
b9ba6d
 	      char *tmpbuf = buffer;
b9ba6d
 	      size_t tmplen = buflen;
b9ba6d
+	      bool use_malloc = false;
b9ba6d
 
b9ba6d
 	      for (int i = 0; i < mystart; i++)
b9ba6d
 		{
b9ba6d
@@ -316,21 +319,36 @@ getgrent_next_nss (ent_t *ent, char *buf
b9ba6d
 						   tmpbuf, tmplen, errnop))
b9ba6d
 			 == NSS_STATUS_TRYAGAIN
b9ba6d
 			 && *errnop == ERANGE)
b9ba6d
-		    if (tmpbuf == buffer)
b9ba6d
-		      {
b9ba6d
-			tmplen *= 2;
b9ba6d
-			tmpbuf = __alloca (tmplen);
b9ba6d
-		      }
b9ba6d
-		    else
b9ba6d
-		      tmpbuf = extend_alloca (tmpbuf, tmplen, 2 * tmplen);
b9ba6d
+                    {
b9ba6d
+                      if (__libc_use_alloca (tmplen * 2))
b9ba6d
+                        {
b9ba6d
+                          if (tmpbuf == buffer)
b9ba6d
+                            {
b9ba6d
+                              tmplen *= 2;
b9ba6d
+                              tmpbuf = __alloca (tmplen);
b9ba6d
+                            }
b9ba6d
+                          else
b9ba6d
+                            tmpbuf = extend_alloca (tmpbuf, tmplen, tmplen * 2);
b9ba6d
+                        }
b9ba6d
+                      else
b9ba6d
+                        {
b9ba6d
+                          tmplen *= 2;
b9ba6d
+                          char *newbuf = realloc (use_malloc ? tmpbuf : NULL, tmplen);
b9ba6d
+                    
b9ba6d
+                          if (newbuf == NULL)
b9ba6d
+                            {
b9ba6d
+                              status = NSS_STATUS_TRYAGAIN;
b9ba6d
+			      goto done;
b9ba6d
+                            }
b9ba6d
+                          use_malloc = true;
b9ba6d
+                          tmpbuf = newbuf;
b9ba6d
+                        }
b9ba6d
+                    }
b9ba6d
 
b9ba6d
 		  if (__builtin_expect  (status != NSS_STATUS_NOTFOUND, 1))
b9ba6d
 		    {
b9ba6d
 		      if (__builtin_expect  (status != NSS_STATUS_SUCCESS, 0))
b9ba6d
-			{
b9ba6d
-			  free (mygroups);
b9ba6d
-			  return status;
b9ba6d
-			}
b9ba6d
+		        goto done;
b9ba6d
 
b9ba6d
 		      if (!in_blacklist (grpbuf.gr_name,
b9ba6d
 					 strlen (grpbuf.gr_name), ent)
b9ba6d
@@ -348,11 +366,17 @@ getgrent_next_nss (ent_t *ent, char *buf
b9ba6d
 			}
b9ba6d
 		    }
b9ba6d
 		}
b9ba6d
+
b9ba6d
+		status = NSS_STATUS_NOTFOUND;
b9ba6d
+
b9ba6d
+ done:
b9ba6d
+		if (use_malloc)
b9ba6d
+		  free (tmpbuf);
b9ba6d
 	    }
b9ba6d
 
b9ba6d
 	  free (mygroups);
b9ba6d
 
b9ba6d
-	  return NSS_STATUS_NOTFOUND;
b9ba6d
+	  return status;
b9ba6d
 	}
b9ba6d
 
b9ba6d
       free (mygroups);
b9ba6d
@@ -506,6 +530,7 @@ _nss_compat_initgroups_dyn (const char *
b9ba6d
   char *tmpbuf;
b9ba6d
   enum nss_status status;
b9ba6d
   ent_t intern = { true, false, false, NULL, {NULL, 0, 0} };
b9ba6d
+  bool use_malloc = false;
b9ba6d
 
b9ba6d
   status = internal_setgrent (&intern;;
b9ba6d
   if (status != NSS_STATUS_SUCCESS)
b9ba6d
@@ -519,13 +544,32 @@ _nss_compat_initgroups_dyn (const char *
b9ba6d
 					    user, group, start, size,
b9ba6d
 					    groupsp, limit, errnop))
b9ba6d
 	     == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
b9ba6d
-	tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
b9ba6d
+        if (__libc_use_alloca (buflen * 2))
b9ba6d
+          tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
b9ba6d
+        else
b9ba6d
+          {
b9ba6d
+            buflen *= 2;
b9ba6d
+            char *newbuf = realloc (use_malloc ? tmpbuf : NULL, buflen);
b9ba6d
+            if (newbuf == NULL)
b9ba6d
+              {
b9ba6d
+                status = NSS_STATUS_TRYAGAIN;
b9ba6d
+                goto done;
b9ba6d
+              }
b9ba6d
+            use_malloc = true;
b9ba6d
+            tmpbuf = newbuf;
b9ba6d
+          }
b9ba6d
     }
b9ba6d
   while (status == NSS_STATUS_SUCCESS);
b9ba6d
 
b9ba6d
+  status = NSS_STATUS_SUCCESS;
b9ba6d
+
b9ba6d
+ done:
b9ba6d
+  if (use_malloc)
b9ba6d
+    free (tmpbuf);
b9ba6d
+
b9ba6d
   internal_endgrent (&intern;;
b9ba6d
 
b9ba6d
-  return NSS_STATUS_SUCCESS;
b9ba6d
+  return status;
b9ba6d
 }
b9ba6d
 
b9ba6d