arrfab / rpms / glibc

Forked from rpms/glibc 4 years ago
Clone

Blame SOURCES/glibc-rh1138520.patch

147e83
commit af37a8a3496327a6e5617a2c76f17aa1e8db835e
147e83
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
147e83
Date:   Mon Jan 27 11:32:44 2014 +0530
147e83
147e83
    Avoid undefined behaviour in netgroupcache
147e83
    
147e83
    Using a buffer after it has been reallocated is undefined behaviour,
147e83
    so get offsets of the triplets in the old buffer before reallocating
147e83
    it.
147e83
147e83
commit 5d41dadf31bc8a2f9c34c40d52a442d3794e405c
147e83
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
147e83
Date:   Fri Jan 24 13:51:15 2014 +0530
147e83
147e83
    Adjust pointers to triplets in netgroup query data (BZ #16474)
147e83
    
147e83
    The _nss_*_getnetgrent_r query populates the netgroup results in the
147e83
    allocated buffer and then sets the result triplet to point to strings
147e83
    in the buffer.  This is a problem when the buffer is reallocated since
147e83
    the pointers to the triplet strings are no longer valid.  The pointers
147e83
    need to be adjusted so that they now point to strings in the
147e83
    reallocated buffer.
147e83
147e83
commit 980cb5180e1b71224a57ca52b995c959b7148c09
147e83
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
147e83
Date:   Thu Jan 16 10:20:22 2014 +0530
147e83
147e83
    Don't use alloca in addgetnetgrentX (BZ #16453)
147e83
147e83
    addgetnetgrentX has a buffer which is grown as per the needs of the
147e83
    requested size either by using alloca or by falling back to malloc if
147e83
    the size is larger than 1K.  There are two problems with the alloca
147e83
    bits: firstly, it doesn't really extend the buffer since it does not
147e83
    use the return value of the extend_alloca macro, which is the location
147e83
    of the reallocated buffer.  Due to this the buffer does not actually
147e83
    extend itself and hence a subsequent write may overwrite stuff on the
147e83
    stack.
147e83
147e83
    The second problem is more subtle - the buffer growth on the stack is
147e83
    discontinuous due to block scope local variables.  Combine that with
147e83
    the fact that unlike realloc, extend_alloca does not copy over old
147e83
    content and you have a situation where the buffer just has garbage in
147e83
    the space where it should have had data.
147e83
147e83
    This could have been fixed by adding code to copy over old data
147e83
    whenever we call extend_alloca, but it seems unnecessarily
147e83
    complicated.  This code is not exactly a performance hotspot (it's
147e83
    called when there is a cache miss, so factors like network lookup or
147e83
    file reads will dominate over memory allocation/reallocation), so this
147e83
    premature optimization is unnecessary.
147e83
    
147e83
    Thanks Brad Hubbard <bhubbard@redhat.com> for his help with debugging
147e83
    the problem.
147e83
147e83
diff -pruN glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c
147e83
--- glibc-2.17-c758a686/nscd/netgroupcache.c	2014-04-09 12:13:58.618582111 +0530
147e83
+++ glibc-2.17-c758a686/nscd/netgroupcache.c	2014-04-09 12:07:21.486598665 +0530
147e83
@@ -93,7 +93,6 @@ addgetnetgrentX (struct database_dyn *db
147e83
   size_t buffilled = sizeof (*dataset);
147e83
   char *buffer = NULL;
147e83
   size_t nentries = 0;
147e83
-  bool use_malloc = false;
147e83
   size_t group_len = strlen (key) + 1;
147e83
   union
147e83
   {
147e83
@@ -138,7 +137,7 @@ addgetnetgrentX (struct database_dyn *db
147e83
     }
147e83
 
147e83
   memset (&data, '\0', sizeof (data));
147e83
-  buffer = alloca (buflen);
147e83
+  buffer = xmalloc (buflen);
147e83
   first_needed.elem.next = &first_needed.elem;
147e83
   memcpy (first_needed.elem.name, key, group_len);
147e83
   data.needed_groups = &first_needed.elem;
147e83
@@ -218,21 +217,24 @@ addgetnetgrentX (struct database_dyn *db
147e83
 
147e83
 				if (buflen - req->key_len - bufused < needed)
147e83
 				  {
147e83
-				    size_t newsize = MAX (2 * buflen,
147e83
-							  buflen + 2 * needed);
147e83
-				    if (use_malloc || newsize > 1024 * 1024)
147e83
-				      {
147e83
-					buflen = newsize;
147e83
-					char *newbuf = xrealloc (use_malloc
147e83
-								 ? buffer
147e83
-								 : NULL,
147e83
-								 buflen);
147e83
-
147e83
-					buffer = newbuf;
147e83
-					use_malloc = true;
147e83
-				      }
147e83
-				    else
147e83
-				      extend_alloca (buffer, buflen, newsize);
147e83
+				    buflen += MAX (buflen, 2 * needed);
147e83
+				    /* Save offset in the old buffer.  We don't
147e83
+				       bother with the NULL check here since
147e83
+				       we'll do that later anyway.  */
147e83
+				    size_t nhostdiff = nhost - buffer;
147e83
+				    size_t nuserdiff = nuser - buffer;
147e83
+				    size_t ndomaindiff = ndomain - buffer;
147e83
+
147e83
+				    char *newbuf = xrealloc (buffer, buflen);
147e83
+				    /* Fix up the triplet pointers into the new
147e83
+				       buffer.  */
147e83
+				    nhost = (nhost ? newbuf + nhostdiff
147e83
+					     : NULL);
147e83
+				    nuser = (nuser ? newbuf + nuserdiff
147e83
+					     : NULL);
147e83
+				    ndomain = (ndomain ? newbuf + ndomaindiff
147e83
+					       : NULL);
147e83
+				    buffer = newbuf;
147e83
 				  }
147e83
 
147e83
 				nhost = memcpy (buffer + bufused,
147e83
@@ -299,18 +301,8 @@ addgetnetgrentX (struct database_dyn *db
147e83
 		      }
147e83
 		    else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
147e83
 		      {
147e83
-			size_t newsize = 2 * buflen;
147e83
-			if (use_malloc || newsize > 1024 * 1024)
147e83
-			  {
147e83
-			    buflen = newsize;
147e83
-			    char *newbuf = xrealloc (use_malloc
147e83
-						     ? buffer : NULL, buflen);
147e83
-
147e83
-			    buffer = newbuf;
147e83
-			    use_malloc = true;
147e83
-			  }
147e83
-			else
147e83
-			  extend_alloca (buffer, buflen, newsize);
147e83
+			buflen *= 2;
147e83
+			buffer = xrealloc (buffer, buflen);
147e83
 		      }
147e83
 		  }
147e83
 
147e83
@@ -446,8 +438,7 @@ addgetnetgrentX (struct database_dyn *db
147e83
     }
147e83
 
147e83
  out:
147e83
-  if (use_malloc)
147e83
-    free (buffer);
147e83
+  free (buffer);
147e83
 
147e83
   *resultp = dataset;
147e83