Blame SOURCES/glibc-rh705465.patch

4999bf
2011-11-07  Andreas Schwab  <schwab@redhat.com>
4999bf
4999bf
	* nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn):
4999bf
	Fix size of allocated buffer.
4999bf
4999bf
2011-05-10  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	[BZ #11257]
4999bf
	* grp/initgroups.c (internal_getgrouplist): When we found the service
4999bf
	list through the initgroups entry in nsswitch.conf do not always
4999bf
	continue on a successful lookup.  Don't always use the
4999bf
	__nss_group_data-ase value if it is set.
4999bf
	* nss/nsswitch.conf (initgroups): Change action for successful db
4999bf
	lookup to continue for compatibility.
4999bf
4999bf
2011-05-06  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	* nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): Return
4999bf
	NSS_STATUS_NOTFOUND if no record was found.
4999bf
4999bf
2011-04-29  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	* grp/initgroups.c (internal_getgrouplist): Prefer initgroups setting
4999bf
	to groups setting in database lookup.
4999bf
	* nss/nsswitch.conf: Add initgroups entry.
4999bf
4999bf
2011-04-21  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	* nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): Fix
4999bf
	problem in reallocation in last patch.
4999bf
4999bf
2011-04-19  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	* nss/nss_files/files-initgroups.c: New file.
4999bf
	* nss/Makefile (libnss_files-routines): Add files-initgroups.
4999bf
	* nss/Versions (libnss_files) [GLIBC_PRIVATE]: Export
4999bf
	_nss_files_initgroups_dyn.
4999bf
4999bf
2011-01-13  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	[BZ #10484]
4999bf
	* nss/nss_files/files-hosts.c (HOST_DB_LOOKUP): Handle overflows of
4999bf
	temporary buffer used to handle multi lookups locally.
4999bf
	* include/alloca.h: Add libc_hidden_proto for __libc_alloca_cutoff.
4999bf
4999bf
2011-01-13  Ulrich Drepper  <drepper@gmail.com>
4999bf
4999bf
	[BZ #10484]
4999bf
	* Versions [libc] (GLIBC_PRIVATE): Export __libc_alloca_cutoff.
4999bf
	* alloca_cutoff.c: Add libc_hidden_def.
4999bf
4999bf
Index: glibc-2.12-2-gc4ccff1/grp/initgroups.c
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/grp/initgroups.c
4999bf
+++ glibc-2.12-2-gc4ccff1/grp/initgroups.c
4999bf
@@ -43,6 +43,8 @@ extern int __nss_group_lookup (service_u
4999bf
 extern void *__nss_lookup_function (service_user *ni, const char *fct_name);
4999bf
 
4999bf
 extern service_user *__nss_group_database attribute_hidden;
4999bf
+static service_user *initgroups_database;
4999bf
+static bool use_initgroups_entry;
4999bf
 
4999bf
 
4999bf
 #include "compat-initgroups.c"
4999bf
@@ -67,32 +69,41 @@ internal_getgrouplist (const char *user,
4999bf
     }
4999bf
 #endif
4999bf
 
4999bf
-  service_user *nip = NULL;
4999bf
-  initgroups_dyn_function fct;
4999bf
   enum nss_status status = NSS_STATUS_UNAVAIL;
4999bf
-  int no_more;
4999bf
-  /* Start is one, because we have the first group as parameter.  */
4999bf
-  long int start = 1;
4999bf
+  int no_more = 0;
4999bf
 
4999bf
   /* Never store more than the starting *SIZE number of elements.  */
4999bf
   assert (*size > 0);
4999bf
   (*groupsp)[0] = group;
4999bf
+  /* Start is one, because we have the first group as parameter.  */
4999bf
+  long int start = 1;
4999bf
 
4999bf
-  if (__nss_group_database != NULL)
4999bf
+  if (initgroups_database == NULL)
4999bf
     {
4999bf
-      no_more = 0;
4999bf
-      nip = __nss_group_database;
4999bf
+      no_more = __nss_database_lookup ("initgroups", NULL, "",
4999bf
+				       &initgroups_database);
4999bf
+      if (no_more == 0 && initgroups_database == NULL)
4999bf
+	{
4999bf
+	  if (__nss_group_database == NULL)
4999bf
+	    no_more = __nss_database_lookup ("group", NULL, "compat files",
4999bf
+					     &__nss_group_database);
4999bf
+
4999bf
+	  initgroups_database = __nss_group_database;
4999bf
+	}
4999bf
+      else if (initgroups_database != NULL)
4999bf
+	{
4999bf
+	  assert (no_more == 0);
4999bf
+	  use_initgroups_entry = true;
4999bf
+	}
4999bf
     }
4999bf
-  else
4999bf
-    no_more = __nss_database_lookup ("group", NULL,
4999bf
-				     "compat [NOTFOUND=return] files", &nip;;
4999bf
 
4999bf
+  service_user *nip = initgroups_database;
4999bf
   while (! no_more)
4999bf
     {
4999bf
       long int prev_start = start;
4999bf
 
4999bf
-      fct = __nss_lookup_function (nip, "initgroups_dyn");
4999bf
-
4999bf
+      initgroups_dyn_function fct = __nss_lookup_function (nip,
4999bf
+							   "initgroups_dyn");
4999bf
       if (fct == NULL)
4999bf
 	status = compat_call (nip, user, group, &start, size, groupsp,
4999bf
 			      limit, &errno);
4999bf
@@ -119,7 +130,13 @@ internal_getgrouplist (const char *user,
4999bf
       if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
4999bf
 	__libc_fatal ("illegal status in internal_getgrouplist");
4999bf
 
4999bf
-      if (status != NSS_STATUS_SUCCESS
4999bf
+      /* For compatibility reason we will continue to look for more
4999bf
+	 entries using the next service even though data has already
4999bf
+	 been found if the nsswitch.conf file contained only a 'groups'
4999bf
+	 line and no 'initgroups' line.  If the latter is available
4999bf
+	 we always respect the status.  This means that the default
4999bf
+	 for successful lookups is to return.  */
4999bf
+      if ((use_initgroups_entry || status != NSS_STATUS_SUCCESS)
4999bf
 	  && nss_next_action (nip, status) == NSS_ACTION_RETURN)
4999bf
 	 break;
4999bf
 
4999bf
Index: glibc-2.12-2-gc4ccff1/include/alloca.h
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/include/alloca.h
4999bf
+++ glibc-2.12-2-gc4ccff1/include/alloca.h
4999bf
@@ -14,6 +14,7 @@ extern void *__alloca (size_t __size);
4999bf
 
4999bf
 extern int __libc_use_alloca (size_t size) __attribute__ ((const));
4999bf
 extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const));
4999bf
+libc_hidden_proto (__libc_alloca_cutoff)
4999bf
 
4999bf
 #define __MAX_ALLOCA_CUTOFF	65536
4999bf
 
4999bf
Index: glibc-2.12-2-gc4ccff1/nptl/Versions
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/nptl/Versions
4999bf
+++ glibc-2.12-2-gc4ccff1/nptl/Versions
4999bf
@@ -27,6 +27,7 @@ libc {
4999bf
     pthread_cond_broadcast; pthread_cond_timedwait;
4999bf
   }
4999bf
   GLIBC_PRIVATE {
4999bf
+    __libc_alloca_cutoff;
4999bf
     # Internal libc interface to libpthread
4999bf
     __libc_dl_error_tsd;
4999bf
   }
4999bf
Index: glibc-2.12-2-gc4ccff1/nptl/alloca_cutoff.c
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/nptl/alloca_cutoff.c
4999bf
+++ glibc-2.12-2-gc4ccff1/nptl/alloca_cutoff.c
4999bf
@@ -34,3 +34,4 @@ __libc_alloca_cutoff (size_t size)
4999bf
 			  assume the maximum available stack space.  */
4999bf
 		       ?: __MAX_ALLOCA_CUTOFF * 4));
4999bf
 }
4999bf
+libc_hidden_def (__libc_alloca_cutoff)
4999bf
Index: glibc-2.12-2-gc4ccff1/nss/Makefile
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/nss/Makefile
4999bf
+++ glibc-2.12-2-gc4ccff1/nss/Makefile
4999bf
@@ -63,7 +63,7 @@ vpath %.c $(subdir-dirs)
4999bf
 
4999bf
 
4999bf
 libnss_files-routines	:= $(addprefix files-,$(databases)) \
4999bf
-			   files-have_o_cloexec
4999bf
+			   files-initgroups files-have_o_cloexec
4999bf
 distribute		+= files-XXX.c files-parse.c
4999bf
 
4999bf
 
4999bf
Index: glibc-2.12-2-gc4ccff1/nss/Versions
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/nss/Versions
4999bf
+++ glibc-2.12-2-gc4ccff1/nss/Versions
4999bf
@@ -95,5 +95,7 @@ libnss_files {
4999bf
     _nss_netgroup_parseline;
4999bf
     _nss_files_getpublickey;
4999bf
     _nss_files_getsecretkey;
4999bf
+
4999bf
+    _nss_files_initgroups_dyn;
4999bf
   }
4999bf
 }
4999bf
Index: glibc-2.12-2-gc4ccff1/nss/nss_files/files-hosts.c
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/nss/nss_files/files-hosts.c
4999bf
+++ glibc-2.12-2-gc4ccff1/nss/nss_files/files-hosts.c
4999bf
@@ -129,19 +129,22 @@ _nss_files_get##name##_r (proto,					   
4999bf
 	  && _res_hconf.flags & HCONF_FLAG_MULTI)			      \
4999bf
 	{								      \
4999bf
 	  /* We have to get all host entries from the file.  */		      \
4999bf
-	  const size_t tmp_buflen = MIN (buflen, 4096);			      \
4999bf
-	  char tmp_buffer[tmp_buflen]					      \
4999bf
+	  size_t tmp_buflen = MIN (buflen, 4096);			      \
4999bf
+	  char tmp_buffer_stack[tmp_buflen]				      \
4999bf
 	    __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\
4999bf
+	  char *tmp_buffer = tmp_buffer_stack;				      \
4999bf
 	  struct hostent tmp_result_buf;				      \
4999bf
 	  int naddrs = 1;						      \
4999bf
 	  int naliases = 0;						      \
4999bf
 	  char *bufferend;						      \
4999bf
+	  bool tmp_buffer_malloced = false;				      \
4999bf
 									      \
4999bf
 	  while (result->h_aliases[naliases] != NULL)			      \
4999bf
 	    ++naliases;							      \
4999bf
 									      \
4999bf
 	  bufferend = (char *) &result->h_aliases[naliases + 1];	      \
4999bf
 									      \
4999bf
+	again:								      \
4999bf
 	  while ((status = internal_getent (&tmp_result_buf, tmp_buffer,      \
4999bf
 					    tmp_buflen, errnop H_ERRNO_ARG    \
4999bf
 					    EXTRA_ARGS_VALUE))		      \
4999bf
@@ -182,7 +185,7 @@ _nss_files_get##name##_r (proto,					   
4999bf
 		    }							      \
4999bf
 		  /* If the real name is different add it also to the	      \
4999bf
 		     aliases.  This means that there is a duplication	      \
4999bf
-		     in the alias list but this is really the users	      \
4999bf
+		     in the alias list but this is really the user's	      \
4999bf
 		     problem.  */					      \
4999bf
 		  if (strcmp (old_result->h_name,			      \
4999bf
 			      tmp_result_buf.h_name) != 0)		      \
4999bf
@@ -204,7 +207,7 @@ _nss_files_get##name##_r (proto,					   
4999bf
 		      *errnop = ERANGE;					      \
4999bf
 		      *herrnop = NETDB_INTERNAL;			      \
4999bf
 		      status = NSS_STATUS_TRYAGAIN;			      \
4999bf
-		      break;						      \
4999bf
+		      goto out;						      \
4999bf
 		    }							      \
4999bf
 									      \
4999bf
 		  new_h_addr_list =					      \
4999bf
@@ -268,8 +271,54 @@ _nss_files_get##name##_r (proto,					   
4999bf
 		}							      \
4999bf
 	    }								      \
4999bf
 									      \
4999bf
-	  if (status != NSS_STATUS_TRYAGAIN)				      \
4999bf
+	  if (status == NSS_STATUS_TRYAGAIN)				      \
4999bf
+	    {								      \
4999bf
+	      size_t newsize = 2 * tmp_buflen;				      \
4999bf
+	      if (tmp_buffer_malloced)					      \
4999bf
+		{							      \
4999bf
+		  char *newp = realloc (tmp_buffer, newsize);		      \
4999bf
+		  if (newp != NULL)					      \
4999bf
+		    {							      \
4999bf
+		      assert ((((uintptr_t) newp)			      \
4999bf
+			       & (__alignof__ (struct hostent_data) - 1))     \
4999bf
+			      == 0);					      \
4999bf
+		      tmp_buffer = newp;				      \
4999bf
+		      tmp_buflen = newsize;				      \
4999bf
+		      goto again;					      \
4999bf
+		    }							      \
4999bf
+		}							      \
4999bf
+	      else if (!__libc_use_alloca (buflen + newsize))		      \
4999bf
+		{							      \
4999bf
+		  tmp_buffer = malloc (newsize);			      \
4999bf
+		  if (tmp_buffer != NULL)				      \
4999bf
+		    {							      \
4999bf
+		      assert ((((uintptr_t) tmp_buffer)			      \
4999bf
+			       & (__alignof__ (struct hostent_data) - 1))     \
4999bf
+			      == 0);					      \
4999bf
+		      tmp_buffer_malloced = true;			      \
4999bf
+		      tmp_buflen = newsize;				      \
4999bf
+		      goto again;					      \
4999bf
+		    }							      \
4999bf
+		}							      \
4999bf
+	      else							      \
4999bf
+		{							      \
4999bf
+		  tmp_buffer						      \
4999bf
+		    = extend_alloca (tmp_buffer, tmp_buflen,		      \
4999bf
+				     newsize				      \
4999bf
+				     + __alignof__ (struct hostent_data));    \
4999bf
+		  tmp_buffer = (char *) (((uintptr_t) tmp_buffer	      \
4999bf
+					  + __alignof__ (struct hostent_data) \
4999bf
+					  - 1)				      \
4999bf
+					 & ~(__alignof__ (struct hostent_data)\
4999bf
+					     - 1));			      \
4999bf
+		  goto again;						      \
4999bf
+		}							      \
4999bf
+	    }								      \
4999bf
+	  else								      \
4999bf
 	    status = NSS_STATUS_SUCCESS;				      \
4999bf
+	out:								      \
4999bf
+	  if (tmp_buffer_malloced)					      \
4999bf
+	    free (tmp_buffer);						      \
4999bf
 	}								      \
4999bf
 									      \
4999bf
 									      \
4999bf
Index: glibc-2.12-2-gc4ccff1/nss/nss_files/files-initgroups.c
4999bf
===================================================================
4999bf
--- /dev/null
4999bf
+++ glibc-2.12-2-gc4ccff1/nss/nss_files/files-initgroups.c
4999bf
@@ -0,0 +1,137 @@
4999bf
+/* Initgroups handling in nss_files module.
4999bf
+   Copyright (C) 2011 Free Software Foundation, Inc.
4999bf
+   This file is part of the GNU C Library.
4999bf
+
4999bf
+   The GNU C Library is free software; you can redistribute it and/or
4999bf
+   modify it under the terms of the GNU Lesser General Public
4999bf
+   License as published by the Free Software Foundation; either
4999bf
+   version 2.1 of the License, or (at your option) any later version.
4999bf
+
4999bf
+   The GNU C Library is distributed in the hope that it will be useful,
4999bf
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
4999bf
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
4999bf
+   Lesser General Public License for more details.
4999bf
+
4999bf
+   You should have received a copy of the GNU Lesser General Public
4999bf
+   License along with the GNU C Library; if not, write to the Free
4999bf
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
4999bf
+   02111-1307 USA.  */
4999bf
+
4999bf
+#include <alloca.h>
4999bf
+#include <errno.h>
4999bf
+#include <grp.h>
4999bf
+#include <nss.h>
4999bf
+#include <stdio_ext.h>
4999bf
+#include <string.h>
4999bf
+#include <sys/param.h>
4999bf
+
4999bf
+enum nss_status
4999bf
+_nss_files_initgroups_dyn (const char *user, gid_t group, long int *start,
4999bf
+			   long int *size, gid_t **groupsp, long int limit,
4999bf
+			   int *errnop)
4999bf
+{
4999bf
+  FILE *stream = fopen ("/etc/group", "re");
4999bf
+  if (stream == NULL)
4999bf
+    {
4999bf
+      *errnop = errno;
4999bf
+      return *errnop == ENOMEM ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
4999bf
+    }
4999bf
+
4999bf
+  /* No other thread using this stream.  */
4999bf
+  __fsetlocking (stream, FSETLOCKING_BYCALLER);
4999bf
+
4999bf
+  char *line = NULL;
4999bf
+  size_t linelen = 0;
4999bf
+  enum nss_status status = NSS_STATUS_SUCCESS;
4999bf
+  bool any = false;
4999bf
+
4999bf
+  size_t buflen = 1024;
4999bf
+  void *buffer = alloca (buflen);
4999bf
+  bool buffer_use_malloc = false;
4999bf
+
4999bf
+  gid_t *groups = *groupsp;
4999bf
+
4999bf
+  /* We have to iterate over the entire file.  */
4999bf
+  while (!feof_unlocked (stream))
4999bf
+    {
4999bf
+      ssize_t n = getline (&line, &linelen, stream);
4999bf
+      if (n < 0)
4999bf
+	{
4999bf
+	  if (! feof_unlocked (stream))
4999bf
+	    status = ((*errnop = errno) == ENOMEM
4999bf
+		      ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL);
4999bf
+	  break;
4999bf
+	}
4999bf
+
4999bf
+      struct group grp;
4999bf
+      int res;
4999bf
+      while ((res = _nss_files_parse_grent (line, &grp, buffer, buflen,
4999bf
+					    errnop)) == -1)
4999bf
+	{
4999bf
+	  size_t newbuflen = 2 * buflen;
4999bf
+	  if (buffer_use_malloc || ! __libc_use_alloca (buflen + newbuflen))
4999bf
+	    {
4999bf
+	      void *newbuf = realloc (buffer_use_malloc ? buffer : NULL,
4999bf
+				      newbuflen);
4999bf
+	      if (newbuf == NULL)
4999bf
+		{
4999bf
+		  *errnop = ENOMEM;
4999bf
+		  status = NSS_STATUS_TRYAGAIN;
4999bf
+		  goto out;
4999bf
+		}
4999bf
+	      buffer = newbuf;
4999bf
+	      buflen = newbuflen;
4999bf
+	      buffer_use_malloc = true;
4999bf
+	    }
4999bf
+	  else
4999bf
+	    buffer = extend_alloca (buffer, buflen, newbuflen);
4999bf
+	}
4999bf
+
4999bf
+      if (res > 0 && grp.gr_gid != group)
4999bf
+	for (char **m = grp.gr_mem; *m != NULL; ++m)
4999bf
+	  if (strcmp (*m, user) == 0)
4999bf
+	    {
4999bf
+	      /* Matches user.  Insert this group.  */
4999bf
+	      if (*start == *size)
4999bf
+		{
4999bf
+		  /* Need a bigger buffer.  */
4999bf
+		  if (limit > 0 && *size == limit)
4999bf
+		    /* We reached the maximum.  */
4999bf
+		    goto out;
4999bf
+
4999bf
+		  long int newsize;
4999bf
+		  if (limit <= 0)
4999bf
+		    newsize = 2 * *size;
4999bf
+		  else
4999bf
+		    newsize = MIN (limit, 2 * *size);
4999bf
+
4999bf
+		  gid_t *newgroups = realloc (groups,
4999bf
+					      newsize * sizeof (*groups));
4999bf
+		  if (newgroups == NULL)
4999bf
+		    {
4999bf
+		      *errnop = ENOMEM;
4999bf
+		      status = NSS_STATUS_TRYAGAIN;
4999bf
+		      goto out;
4999bf
+		    }
4999bf
+		  *groupsp = groups = newgroups;
4999bf
+		  *size = newsize;
4999bf
+		}
4999bf
+
4999bf
+	      groups[*start] = grp.gr_gid;
4999bf
+	      *start += 1;
4999bf
+	      any = true;
4999bf
+
4999bf
+	      break;
4999bf
+	    }
4999bf
+    }
4999bf
+
4999bf
+ out:
4999bf
+  /* Free memory.  */
4999bf
+  if (buffer_use_malloc)
4999bf
+    free (buffer);
4999bf
+  free (line);
4999bf
+
4999bf
+  fclose (stream);
4999bf
+
4999bf
+  return status == NSS_STATUS_SUCCESS && !any ? NSS_STATUS_NOTFOUND : status;
4999bf
+}
4999bf
Index: glibc-2.12-2-gc4ccff1/nss/nsswitch.conf
4999bf
===================================================================
4999bf
--- glibc-2.12-2-gc4ccff1.orig/nss/nsswitch.conf
4999bf
+++ glibc-2.12-2-gc4ccff1/nss/nsswitch.conf
4999bf
@@ -5,6 +5,7 @@
4999bf
 
4999bf
 passwd:		db files
4999bf
 group:		db files
4999bf
+initgroups:	db [SUCCESS=continue] files
4999bf
 shadow:		db files
4999bf
 gshadow:	files
4999bf