This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.26-552-g78e806f


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  78e806fd8cd8c918d3bbe1bcdf9091ab365e4a69 (commit)
      from  0ff64d3a18fc5111c54ffd3238231754dfd506dc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=78e806fd8cd8c918d3bbe1bcdf9091ab365e4a69

commit 78e806fd8cd8c918d3bbe1bcdf9091ab365e4a69
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Oct 11 07:01:34 2017 +0200

    nss_files: Use struct scratch_buffer for gethostbyname [BZ #18023]

diff --git a/ChangeLog b/ChangeLog
index f8914f3..26e272e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-10-11  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #18023]
+	* nss/nss_files/files-hosts.c (gethostbyname3_multi): Use struct
+	scratch_buffer.  Eliminate gotos.
+
 2017-10-11  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/ieee754/ldbl-opt/s_clog10l.c: Use
diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c
index 867c10c..763fa39 100644
--- a/nss/nss_files/files-hosts.c
+++ b/nss/nss_files/files-hosts.c
@@ -22,6 +22,7 @@
 #include <arpa/nameser.h>
 #include <netdb.h>
 #include <resolv/resolv-internal.h>
+#include <scratch_buffer.h>
 
 
 /* Get implementation for some internal functions.  */
@@ -121,15 +122,12 @@ gethostbyname3_multi (FILE * stream, const char *name, int af,
 		      int *errnop, int *herrnop, int flags)
 {
   /* We have to get all host entries from the file.  */
-  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 scratch_buffer tmp_buffer;
+  scratch_buffer_init (&tmp_buffer);
   struct hostent tmp_result_buf;
   int naddrs = 1;
   int naliases = 0;
   char *bufferend;
-  bool tmp_buffer_malloced = false;
   enum nss_status status;
 
   while (result->h_aliases[naliases] != NULL)
@@ -137,181 +135,165 @@ gethostbyname3_multi (FILE * stream, const char *name, int af,
 
   bufferend = (char *) &result->h_aliases[naliases + 1];
 
- again:
-  while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer,
-				    tmp_buflen, errnop, herrnop, af,
-				    flags))
-	 == NSS_STATUS_SUCCESS)
+  while (true)
     {
-      int matches = 1;
-      struct hostent *old_result = result;
-      result = &tmp_result_buf;
-      /* The following piece is a bit clumsy but we want to use the
-	 `LOOKUP_NAME_CASE' value.  The optimizer should do its
-	 job.  */
-      do
+      status = internal_getent (stream, &tmp_result_buf, tmp_buffer.data,
+				tmp_buffer.length, errnop, herrnop, af,
+				flags);
+      /* Enlarge the buffer if necessary.  */
+      if (status == NSS_STATUS_TRYAGAIN && *herrnop == NETDB_INTERNAL
+	  && *errnop == ERANGE)
 	{
-	  LOOKUP_NAME_CASE (h_name, h_aliases)
-	    result = old_result;
+	  if (!scratch_buffer_grow (&tmp_buffer))
+	    {
+	      *errnop = ENOMEM;
+	      /* *herrnop and status already have the right value.  */
+	      break;
+	    }
+	  /* Loop around and retry with a larger buffer.  */
 	}
-      while ((matches = 0));
-
-      if (matches)
+      else if (status == NSS_STATUS_SUCCESS)
 	{
-	  /* We could be very clever and try to recycle a few bytes
-	     in the buffer instead of generating new arrays.  But
-	     we are not doing this here since it's more work than
-	     it's worth.  Simply let the user provide a bit bigger
-	     buffer.  */
-	  char **new_h_addr_list;
-	  char **new_h_aliases;
-	  int newaliases = 0;
-	  size_t newstrlen = 0;
-	  int cnt;
-
-	  /* Count the new aliases and the length of the strings.  */
-	  while (tmp_result_buf.h_aliases[newaliases] != NULL)
+	  /* A line was read.  Check that it matches the search
+	     criteria.  */
+
+	  int matches = 1;
+	  struct hostent *old_result = result;
+	  result = &tmp_result_buf;
+	  /* The following piece is a bit clumsy but we want to use
+	     the `LOOKUP_NAME_CASE' value.  The optimizer should do
+	     its job.  */
+	  do
 	    {
-	      char *cp = tmp_result_buf.h_aliases[newaliases];
-	      ++newaliases;
-	      newstrlen += strlen (cp) + 1;
+	      LOOKUP_NAME_CASE (h_name, h_aliases)
+		result = old_result;
 	    }
-	  /* 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 user's
-	     problem.  */
-	  if (strcmp (old_result->h_name,
-		      tmp_result_buf.h_name) != 0)
+	  while ((matches = 0));
+
+	  if (matches)
 	    {
-	      ++newaliases;
-	      newstrlen += strlen (tmp_result_buf.h_name) + 1;
-	    }
+	      /* We could be very clever and try to recycle a few bytes
+		 in the buffer instead of generating new arrays.  But
+		 we are not doing this here since it's more work than
+		 it's worth.  Simply let the user provide a bit bigger
+		 buffer.  */
+	      char **new_h_addr_list;
+	      char **new_h_aliases;
+	      int newaliases = 0;
+	      size_t newstrlen = 0;
+	      int cnt;
+
+	      /* Count the new aliases and the length of the strings.  */
+	      while (tmp_result_buf.h_aliases[newaliases] != NULL)
+		{
+		  char *cp = tmp_result_buf.h_aliases[newaliases];
+		  ++newaliases;
+		  newstrlen += strlen (cp) + 1;
+		}
+	      /* 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 user's
+		 problem.  */
+	      if (strcmp (old_result->h_name,
+			  tmp_result_buf.h_name) != 0)
+		{
+		  ++newaliases;
+		  newstrlen += strlen (tmp_result_buf.h_name) + 1;
+		}
 
-	  /* Make sure bufferend is aligned.  */
-	  assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
+	      /* Make sure bufferend is aligned.  */
+	      assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
 
-	  /* Now we can check whether the buffer is large enough.
-	     16 is the maximal size of the IP address.  */
-	  if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
-	      + roundup (newstrlen, sizeof (char *))
-	      + (naliases + newaliases + 1) * sizeof (char *)
-	      >= buffer + buflen)
-	    {
-	      *errnop = ERANGE;
-	      *herrnop = NETDB_INTERNAL;
-	      status = NSS_STATUS_TRYAGAIN;
-	      goto out;
-	    }
+	      /* Now we can check whether the buffer is large enough.
+		 16 is the maximal size of the IP address.  */
+	      if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
+		  + roundup (newstrlen, sizeof (char *))
+		  + (naliases + newaliases + 1) * sizeof (char *)
+		  >= buffer + buflen)
+		{
+		  *errnop = ERANGE;
+		  *herrnop = NETDB_INTERNAL;
+		  status = NSS_STATUS_TRYAGAIN;
+		  break;
+		}
 
-	  new_h_addr_list =
-	    (char **) (bufferend
-		       + roundup (newstrlen, sizeof (char *))
-		       + 16);
-	  new_h_aliases =
-	    (char **) ((char *) new_h_addr_list
-		       + (naddrs + 2) * sizeof (char *));
+	      new_h_addr_list =
+		(char **) (bufferend
+			   + roundup (newstrlen, sizeof (char *))
+			   + 16);
+	      new_h_aliases =
+		(char **) ((char *) new_h_addr_list
+			   + (naddrs + 2) * sizeof (char *));
 
-	  /* Copy the old data in the new arrays.  */
-	  for (cnt = 0; cnt < naddrs; ++cnt)
-	    new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
+	      /* Copy the old data in the new arrays.  */
+	      for (cnt = 0; cnt < naddrs; ++cnt)
+		new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
 
-	  for (cnt = 0; cnt < naliases; ++cnt)
-	    new_h_aliases[cnt] = old_result->h_aliases[cnt];
+	      for (cnt = 0; cnt < naliases; ++cnt)
+		new_h_aliases[cnt] = old_result->h_aliases[cnt];
 
-	  /* Store the new strings.  */
-	  cnt = 0;
-	  while (tmp_result_buf.h_aliases[cnt] != NULL)
-	    {
-	      new_h_aliases[naliases++] = bufferend;
-	      bufferend = (__stpcpy (bufferend,
-				     tmp_result_buf.h_aliases[cnt])
-			   + 1);
-	      ++cnt;
-	    }
+	      /* Store the new strings.  */
+	      cnt = 0;
+	      while (tmp_result_buf.h_aliases[cnt] != NULL)
+		{
+		  new_h_aliases[naliases++] = bufferend;
+		  bufferend = (__stpcpy (bufferend,
+					 tmp_result_buf.h_aliases[cnt])
+			       + 1);
+		  ++cnt;
+		}
 
-	  if (cnt < newaliases)
-	    {
-	      new_h_aliases[naliases++] = bufferend;
-	      bufferend = __stpcpy (bufferend,
-				    tmp_result_buf.h_name) + 1;
-	    }
+	      if (cnt < newaliases)
+		{
+		  new_h_aliases[naliases++] = bufferend;
+		  bufferend = __stpcpy (bufferend,
+					tmp_result_buf.h_name) + 1;
+		}
 
-	  /* Final NULL pointer.  */
-	  new_h_aliases[naliases] = NULL;
+	      /* Final NULL pointer.  */
+	      new_h_aliases[naliases] = NULL;
 
-	  /* Round up the buffer end address.  */
-	  bufferend += (sizeof (char *)
-			- ((bufferend - (char *) 0)
-			   % sizeof (char *))) % sizeof (char *);
+	      /* Round up the buffer end address.  */
+	      bufferend += (sizeof (char *)
+			    - ((bufferend - (char *) 0)
+			       % sizeof (char *))) % sizeof (char *);
 
-	  /* Now the new address.  */
-	  new_h_addr_list[naddrs++] =
-	    memcpy (bufferend, tmp_result_buf.h_addr,
-		    tmp_result_buf.h_length);
+	      /* Now the new address.  */
+	      new_h_addr_list[naddrs++] =
+		memcpy (bufferend, tmp_result_buf.h_addr,
+			tmp_result_buf.h_length);
 
-	  /* Also here a final NULL pointer.  */
-	  new_h_addr_list[naddrs] = NULL;
+	      /* Also here a final NULL pointer.  */
+	      new_h_addr_list[naddrs] = NULL;
 
-	  /* Store the new array pointers.  */
-	  old_result->h_aliases = new_h_aliases;
-	  old_result->h_addr_list = new_h_addr_list;
+	      /* Store the new array pointers.  */
+	      old_result->h_aliases = new_h_aliases;
+	      old_result->h_addr_list = new_h_addr_list;
 
-	  /* Compute the new buffer end.  */
-	  bufferend = (char *) &new_h_aliases[naliases + 1];
-	  assert (bufferend <= buffer + buflen);
+	      /* Compute the new buffer end.  */
+	      bufferend = (char *) &new_h_aliases[naliases + 1];
+	      assert (bufferend <= buffer + buflen);
 
-	  result = old_result;
-	}
-    }
+	      result = old_result;
+	    } /* If match was found.  */
 
-  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;
-	    }
-	}
+	  /* If no match is found, loop around and fetch another
+	     line.  */
+
+	} /* status == NSS_STATUS_SUCCESS.  */
       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
+	/* internal_getent returned an error.  */
+	break;
+    } /* while (true) */
+
+  /* Propagate the NSS_STATUS_TRYAGAIN error to the caller.  It means
+     that we may not have loaded the complete result.
+     NSS_STATUS_NOTFOUND, however, means that we reached the end of
+     the file successfully.  */
+  if (status != NSS_STATUS_TRYAGAIN)
     status = NSS_STATUS_SUCCESS;
- out:
-  if (tmp_buffer_malloced)
-    free (tmp_buffer);
+
+  scratch_buffer_free (&tmp_buffer);
   return status;
 }
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                   |    6 +
 nss/nss_files/files-hosts.c |  320 ++++++++++++++++++++-----------------------
 2 files changed, 157 insertions(+), 169 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]