about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-12-07 10:01:11 +0000
committerUlrich Drepper <drepper@redhat.com>2008-12-07 10:01:11 +0000
commite87946cce5b1bac5105f97542c93bc3101bde254 (patch)
treea4f9d588edefc73ddda72d6003e91841066c352a
parentf3721ab2dce137e67579959d8992a251d35dcdb7 (diff)
downloadglibc-e87946cce5b1bac5105f97542c93bc3101bde254.tar.gz
glibc-e87946cce5b1bac5105f97542c93bc3101bde254.tar.xz
glibc-e87946cce5b1bac5105f97542c93bc3101bde254.zip
* nis/nss_nis/nis-hosts.c (_nss_nis_gethostbyname4_r): Fix memory
	handling for host name aliases.
-rw-r--r--ChangeLog5
-rw-r--r--nis/nss_nis/nis-hosts.c58
2 files changed, 41 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e18b54de5..5c752d11bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* nis/nss_nis/nis-hosts.c (_nss_nis_gethostbyname4_r): Fix memory
+	handling for host name aliases.
+
 2008-12-05  Ulrich Drepper  <drepper@redhat.com>
 
 	* posix/globtest.sh: Use mktemp to create temporary file and
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index 24d13634d7..8accf53edf 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -485,24 +485,6 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
       return retval;
     }
 
-  struct parser_data data;
-  struct hostent host;
-  int parse_res = parse_line (result, &host, &data, buflen, errnop, AF_UNSPEC,
-			      0);
-  if (__builtin_expect (parse_res < 1, 0))
-    {
-      if (parse_res == -1)
-	{
-	  *herrnop = NETDB_INTERNAL;
-	  return NSS_STATUS_TRYAGAIN;
-	}
-      else
-	{
-	  *herrnop = HOST_NOT_FOUND;
-	  return NSS_STATUS_NOTFOUND;
-	}
-    }
-
   if (*pat == NULL)
     {
       uintptr_t pad = (-(uintptr_t) buffer
@@ -524,16 +506,48 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
       buflen -= sizeof (struct gaih_addrtuple);
     }
 
-  (*pat)->next = NULL;
-  size_t h_name_len = strlen (host.h_name);
-  if (h_name_len >= buflen)
+  uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data);
+  buffer += pad;
+
+  struct parser_data *data = (void *) buffer;
+
+  if (__builtin_expect (buflen < sizeof *data + 1 + pad, 0))
     goto erange;
-  (*pat)->name = memcpy (buffer, host.h_name, h_name_len + 1);
+  buflen -= pad;
+
+  struct hostent host;
+  int parse_res = parse_line (result, &host, data, buflen, errnop, AF_UNSPEC,
+			      0);
+  if (__builtin_expect (parse_res < 1, 0))
+    {
+      if (parse_res == -1)
+	{
+	  *herrnop = NETDB_INTERNAL;
+	  return NSS_STATUS_TRYAGAIN;
+	}
+      else
+	{
+	  *herrnop = HOST_NOT_FOUND;
+	  return NSS_STATUS_NOTFOUND;
+	}
+    }
+
+  (*pat)->next = NULL;
   (*pat)->family = host.h_addrtype;
   memcpy ((*pat)->addr, host.h_addr_list[0], host.h_length);
   (*pat)->scopeid = 0;
   assert (host.h_addr_list[1] == NULL);
 
+  /* Undo the alignment for parser_data.  */
+  buffer -= pad;
+  buflen += pad;
+
+  size_t h_name_len = strlen (host.h_name) + 1;
+  if (h_name_len >= buflen)
+    goto erange;
+  /* Potentially the string and the destination buffer overlap.  */
+  (*pat)->name = memmove (buffer, host.h_name, h_name_len);
+
   free (result);
 
   return NSS_STATUS_SUCCESS;