about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-01-13 11:28:17 -0500
committerUlrich Drepper <drepper@gmail.com>2011-01-13 11:28:17 -0500
commit451f001b50870604e1f2daef12f04f9f460d3997 (patch)
tree8e416fd4d483cfc1f654f4ad91df292a9246ee2f
parent0876917582041d17a9eb6b08894c1123a2affe74 (diff)
downloadglibc-451f001b50870604e1f2daef12f04f9f460d3997.tar.gz
glibc-451f001b50870604e1f2daef12f04f9f460d3997.tar.xz
glibc-451f001b50870604e1f2daef12f04f9f460d3997.zip
Handle long lines in host lookups in the right place.
-rw-r--r--ChangeLog6
-rw-r--r--NEWS4
-rw-r--r--nptl/ChangeLog5
-rw-r--r--nptl/Versions1
-rw-r--r--nss/nss_files/files-hosts.c61
5 files changed, 69 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index ee705196c3..b1d391c064 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-01-13  Ulrich Drepper  <drepper@gmail.com>
+
+	[BZ #10484]
+	* nss/nss_files/files-hosts.c (HOST_DB_LOOKUP): Handle overflows of
+	temporary buffer used to handle multi lookups locally.
+
 2011-01-12  Ulrich Drepper  <drepper@gmail.com>
 
 	* elf/dl-dst.h (DL_DST_REQUIRED): Allow l_origin to be NULL when
diff --git a/NEWS b/NEWS
index 6abb2808ed..a3025ee7c0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2011-1-12
+GNU C Library NEWS -- history of user-visible changes.  2011-1-13
 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -9,7 +9,7 @@ Version 2.13
 
 * The following bugs are resolved with this release:
 
-  3268, 7066, 10085, 10851, 11149, 11155, 11611, 11640, 11655, 11701,
+  3268, 7066, 10085, 10484, 10851, 11149, 11155, 11611, 11640, 11655, 11701,
   11840, 11856, 11883, 11903, 11904, 11968, 11979, 12005, 12037,
   12067, 12077, 12078, 12092, 12093, 12107, 12108, 12113, 12140,
   12159, 12167, 12191, 12194, 12201, 12204, 12205, 12207, 12348, 12394
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index e3bfd0000b..97400e5b3a 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,8 @@
+2011-01-13  Ulrich Drepper  <drepper@gmail.com>
+
+	[BZ #10484]
+	* Versions [libc] (GLIBC_PRIVATE): Export __libc_alloca_cutoff.
+
 2010-10-13  H.J. Lu  <hongjiu.lu@intel.com>
 
 	[BZ #12113]
diff --git a/nptl/Versions b/nptl/Versions
index f74941fa92..5a884202f1 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -27,6 +27,7 @@ libc {
     pthread_cond_broadcast; pthread_cond_timedwait;
   }
   GLIBC_PRIVATE {
+    __libc_alloca_cutoff;
     # Internal libc interface to libpthread
     __libc_dl_error_tsd;
   }
diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c
index e5f5b48b72..83de650756 100644
--- a/nss/nss_files/files-hosts.c
+++ b/nss/nss_files/files-hosts.c
@@ -1,5 +1,5 @@
 /* Hosts file parser in nss_files module.
-   Copyright (C) 1996-2001, 2003-2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1996-2001, 2003-2009, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -129,19 +129,22 @@ _nss_files_get##name##_r (proto,					      \
 	  && _res_hconf.flags & HCONF_FLAG_MULTI)			      \
 	{								      \
 	  /* We have to get all host entries from the file.  */		      \
-	  const size_t tmp_buflen = MIN (buflen, 4096);			      \
-	  char tmp_buffer[tmp_buflen]					      \
+	  size_t tmp_buflen = MIN (buflen, 4096);			      \
+	  char tmp_buffer_stack[tmp_buflen]				      \
 	    __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\
+	  char *tmp_buffer = tmp_buffer_stack;				      \
 	  struct hostent tmp_result_buf;				      \
 	  int naddrs = 1;						      \
 	  int naliases = 0;						      \
 	  char *bufferend;						      \
+	  bool tmp_buffer_malloced = false;				      \
 									      \
 	  while (result->h_aliases[naliases] != NULL)			      \
 	    ++naliases;							      \
 									      \
 	  bufferend = (char *) &result->h_aliases[naliases + 1];	      \
 									      \
+	again:								      \
 	  while ((status = internal_getent (&tmp_result_buf, tmp_buffer,      \
 					    tmp_buflen, errnop H_ERRNO_ARG    \
 					    EXTRA_ARGS_VALUE))		      \
@@ -182,7 +185,7 @@ _nss_files_get##name##_r (proto,					      \
 		    }							      \
 		  /* If the real name is different add it also to the	      \
 		     aliases.  This means that there is a duplication	      \
-		     in the alias list but this is really the users	      \
+		     in the alias list but this is really the user's	      \
 		     problem.  */					      \
 		  if (strcmp (old_result->h_name,			      \
 			      tmp_result_buf.h_name) != 0)		      \
@@ -204,7 +207,7 @@ _nss_files_get##name##_r (proto,					      \
 		      *errnop = ERANGE;					      \
 		      *herrnop = NETDB_INTERNAL;			      \
 		      status = NSS_STATUS_TRYAGAIN;			      \
-		      break;						      \
+		      goto out;						      \
 		    }							      \
 									      \
 		  new_h_addr_list =					      \
@@ -268,8 +271,54 @@ _nss_files_get##name##_r (proto,					      \
 		}							      \
 	    }								      \
 									      \
-	  if (status != NSS_STATUS_TRYAGAIN)				      \
+	  if (status == NSS_STATUS_TRYAGAIN)				      \
+	    {								      \
+	      size_t newsize = 2 * tmp_buflen;				      \
+	      if (tmp_buffer_malloced)					      \
+		{							      \
+		  char *newp = realloc (tmp_buffer, newsize);		      \
+		  if (newp != NULL)					      \
+		    {							      \
+		      assert ((((uintptr_t) newp)			      \
+			       & (__alignof__ (struct hostent_data) - 1))     \
+			      == 0);					      \
+		      tmp_buffer = newp;				      \
+		      tmp_buflen = newsize;				      \
+		      goto again;					      \
+		    }							      \
+		}							      \
+	      else if (!__libc_use_alloca (buflen + newsize))		      \
+		{							      \
+		  tmp_buffer = malloc (newsize);			      \
+		  if (tmp_buffer != NULL)				      \
+		    {							      \
+		      assert ((((uintptr_t) tmp_buffer)			      \
+			       & (__alignof__ (struct hostent_data) - 1))     \
+			      == 0);					      \
+		      tmp_buffer_malloced = true;			      \
+		      tmp_buflen = newsize;				      \
+		      goto again;					      \
+		    }							      \
+		}							      \
+	      else							      \
+		{							      \
+		  tmp_buffer						      \
+		    = extend_alloca (tmp_buffer, tmp_buflen,		      \
+				     newsize				      \
+				     + __alignof__ (struct hostent_data));    \
+		  tmp_buffer = (char *) (((uintptr_t) tmp_buffer	      \
+					  + __alignof__ (struct hostent_data) \
+					  - 1)				      \
+					 & ~(__alignof__ (struct hostent_data)\
+					     - 1));			      \
+		  goto again;						      \
+		}							      \
+	    }								      \
+	  else								      \
 	    status = NSS_STATUS_SUCCESS;				      \
+	out:								      \
+	  if (tmp_buffer_malloced)					      \
+	    free (tmp_buffer);						      \
 	}								      \
 									      \
 									      \