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.23-293-g0667467


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  066746783d6c6c0f61b39c741177e24a9b398a20 (commit)
       via  1c3490d4b29fc5b3f30dd6b13082046aee94443d (commit)
       via  c9b0e6a432e827b61f12eb52c2aaeadc77b64461 (commit)
      from  eb3b8a4924502e508d5b353ed75f39826d2c9466 (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=066746783d6c6c0f61b39c741177e24a9b398a20

commit 066746783d6c6c0f61b39c741177e24a9b398a20
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed May 4 14:45:17 2016 +0200

    getnameinfo: Return EAI_OVERFLOW in more cases [BZ #19787]
    
    The AF_LOCAL and AF_INET/AF_INET6 non-numerci service conversion
    did not return EAI_OVERFLOW if the supplied buffer was too small,
    silently returning truncated data.  In the AF_INET/AF_INET6
    numeric cases, the snprintf return value checking was incorrect.

diff --git a/ChangeLog b/ChangeLog
index 833cc64..45e8375 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2016-05-04  Florian Weimer  <fweimer@redhat.com>
 
+	[BZ #19787]
+	* inet/getnameinfo.c (check_sprintf_result): New function.
+	(CHECKED_SNPRINTF): New macro.
+	(gni_host_inet_numeric): Use CHECKED_SNPRINTF to write the scope
+	to the host buffer.
+	(gni_host_local): Use checked_copy to copy the host name.
+	(gni_serv_inet): Use CHECKED_SNPRINTF to write the service name.
+	(gni_serv_local): Use checked_copy to copy the service name.
+	(getnameinfo): Remove unnecessary truncation of result buffers.
+
+2016-05-04  Florian Weimer  <fweimer@redhat.com>
+
 	* inet/getnameinfo.c (gni_host_inet_numeric): Return EAI_OVERFLOW
 	in case of inet_ntop failure.
 
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index c8de163..283da55 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -187,6 +187,39 @@ nrl_domainname (void)
   return domain;
 };
 
+/* Copy a string to a destination buffer with length checking.  Return
+   EAI_OVERFLOW if the buffer is not large enough, and 0 on
+   success.  */
+static int
+checked_copy (char *dest, size_t destlen, const char *source)
+{
+  size_t source_length = strlen (source);
+  if (source_length + 1 > destlen)
+    return EAI_OVERFLOW;
+  memcpy (dest, source, source_length + 1);
+  return 0;
+}
+
+/* Helper function for CHECKED_SNPRINTF below.  */
+static int
+check_sprintf_result (int result, size_t destlen)
+{
+  if (result < 0)
+    return EAI_SYSTEM;
+  if ((size_t) result >= destlen)
+    /* If ret == destlen, there was no room for the terminating NUL
+       character.  */
+    return EAI_OVERFLOW;
+  return 0;
+}
+
+/* Format a string in the destination buffer.  Return 0 on success,
+   EAI_OVERFLOW in case the buffer is too small, or EAI_SYSTEM on any
+   other error.  */
+#define CHECKED_SNPRINTF(dest, destlen, format, ...)			\
+  check_sprintf_result							\
+    (__snprintf (dest, destlen, format, __VA_ARGS__), destlen)
+
 /* Convert host name, AF_INET/AF_INET6 case, name only.  */
 static int
 gni_host_inet_name (struct scratch_buffer *tmpbuf,
@@ -312,41 +345,22 @@ gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
       uint32_t scopeid = sin6p->sin6_scope_id;
       if (scopeid != 0)
 	{
-	  /* Buffer is >= IFNAMSIZ+1.  */
-	  char scopebuf[IFNAMSIZ + 1];
-	  char *scopeptr;
-	  int ni_numericscope = 0;
-	  size_t real_hostlen = __strnlen (host, hostlen);
-	  size_t scopelen = 0;
-
-	  scopebuf[0] = SCOPE_DELIMITER;
-	  scopebuf[1] = '\0';
-	  scopeptr = &scopebuf[1];
+	  size_t used_hostlen = __strnlen (host, hostlen);
+	  /* Location of the scope string in the host buffer.  */
+	  char *scope_start = host + used_hostlen;
+	  size_t scope_length = hostlen - used_hostlen;
 
 	  if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
 	      || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr))
 	    {
-	      if (if_indextoname (scopeid, scopeptr) == NULL)
-		++ni_numericscope;
-	      else
-		scopelen = strlen (scopebuf);
+	      char scopebuf[IFNAMSIZ];
+	      if (if_indextoname (scopeid, scopebuf) != NULL)
+		return CHECKED_SNPRINTF
+		  (scope_start, scope_length,
+		   "%c%s", SCOPE_DELIMITER, scopebuf);
 	    }
-	  else
-	    ++ni_numericscope;
-
-	  if (ni_numericscope)
-	    scopelen = 1 + __snprintf (scopeptr,
-				       (scopebuf
-					+ sizeof scopebuf
-					- scopeptr),
-				       "%u", scopeid);
-
-	  if (real_hostlen + scopelen + 1 > hostlen)
-	    /* Signal the buffer is too small.  This is
-	       what inet_ntop does.  */
-	    return EAI_OVERFLOW;
-	  else
-	    memcpy (host + real_hostlen, scopebuf, scopelen + 1);
+	  return CHECKED_SNPRINTF
+	    (scope_start, scope_length, "%c%u", SCOPE_DELIMITER, scopeid);
 	}
     }
   else
@@ -385,23 +399,17 @@ gni_host_local (struct scratch_buffer *tmpbuf,
 		const struct sockaddr *sa, socklen_t addrlen,
 		char *host, socklen_t hostlen, int flags)
 {
-
   if (!(flags & NI_NUMERICHOST))
     {
       struct utsname utsname;
-
-      if (!uname (&utsname))
-	{
-	  strncpy (host, utsname.nodename, hostlen);
-	  return 0;
-	}
+      if (uname (&utsname) == 0)
+	return checked_copy (host, hostlen, utsname.nodename);
     }
 
   if (flags & NI_NAMEREQD)
     return EAI_NONAME;
 
-  strncpy (host, "localhost", hostlen);
-  return 0;
+  return checked_copy (host, hostlen, "localhost");
 }
 
 /* Convert the host part of an AF_LOCAK socket address.   */
@@ -455,15 +463,10 @@ gni_serv_inet (struct scratch_buffer *tmpbuf,
 	    break;
 	}
       if (s)
-	{
-	  strncpy (serv, s->s_name, servlen);
-	  return 0;
-	}
+	return checked_copy (serv, servlen, s->s_name);
       /* Fall through to numeric conversion.  */
     }
-  if (__snprintf (serv, servlen, "%d", ntohs (sinp->sin_port)) + 1 > servlen)
-      return EAI_OVERFLOW;
-  return 0;
+  return CHECKED_SNPRINTF (serv, servlen, "%d", ntohs (sinp->sin_port));
 }
 
 /* Convert service to string, AF_LOCAL variant.  */
@@ -472,8 +475,8 @@ gni_serv_local (struct scratch_buffer *tmpbuf,
 	       const struct sockaddr *sa, socklen_t addrlen,
 	       char *serv, socklen_t servlen, int flags)
 {
-  strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
-  return 0;
+  return checked_copy
+    (serv, servlen, ((const struct sockaddr_un *) sa)->sun_path);
 }
 
 /* Convert service to string, dispatching to the implementations
@@ -554,10 +557,6 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 	}
     }
 
-  if (host && (hostlen > 0))
-    host[hostlen-1] = 0;
-  if (serv && (servlen > 0))
-    serv[servlen-1] = 0;
   scratch_buffer_free (&tmpbuf);
   return 0;
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1c3490d4b29fc5b3f30dd6b13082046aee94443d

commit 1c3490d4b29fc5b3f30dd6b13082046aee94443d
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed May 4 14:35:23 2016 +0200

    getnameinfo: Avoid calling strnlen on uninitialized buffer
    
    In the numeric AF_INET/AF_INET6 case, if inet_ntop fails
    as the result of a short host buffer, we used to call strnlen
    on the uninitialized host buffer.

diff --git a/ChangeLog b/ChangeLog
index 9d2ab7c..833cc64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2016-05-04  Florian Weimer  <fweimer@redhat.com>
 
+	* inet/getnameinfo.c (gni_host_inet_numeric): Return EAI_OVERFLOW
+	in case of inet_ntop failure.
+
+2016-05-04  Florian Weimer  <fweimer@redhat.com>
+
 	* inet/getnameinfo.c (gni_host_inet_name): Use temporaries to
 	avoid long lines.
 	(gni_host_inet_numeric): Likewise.  Reduce scope of local
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index c649c49..c8de163 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -303,12 +303,12 @@ gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
 		       const struct sockaddr *sa, socklen_t addrlen,
 		       char *host, socklen_t hostlen, int flags)
 {
-  const char *c;
   if (sa->sa_family == AF_INET6)
     {
       const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa;
-      c = inet_ntop (AF_INET6,
-		     (const void *) &sin6p->sin6_addr, host, hostlen);
+      if (inet_ntop (AF_INET6, &sin6p->sin6_addr, host, hostlen) == NULL)
+	return EAI_OVERFLOW;
+
       uint32_t scopeid = sin6p->sin6_scope_id;
       if (scopeid != 0)
 	{
@@ -344,7 +344,7 @@ gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
 	  if (real_hostlen + scopelen + 1 > hostlen)
 	    /* Signal the buffer is too small.  This is
 	       what inet_ntop does.  */
-	    c = NULL;
+	    return EAI_OVERFLOW;
 	  else
 	    memcpy (host + real_hostlen, scopebuf, scopelen + 1);
 	}
@@ -352,10 +352,9 @@ gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
   else
     {
       const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
-      c = inet_ntop (AF_INET, &sinp->sin_addr, host, hostlen);
+      if (inet_ntop (AF_INET, &sinp->sin_addr, host, hostlen) == NULL)
+	return EAI_OVERFLOW;
     }
-  if (c == NULL)
-    return EAI_OVERFLOW;
   return 0;
 }
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c9b0e6a432e827b61f12eb52c2aaeadc77b64461

commit c9b0e6a432e827b61f12eb52c2aaeadc77b64461
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed May 4 14:35:12 2016 +0200

    getnameinfo: Reduce line length and add missing comments

diff --git a/ChangeLog b/ChangeLog
index 8fcb047..9d2ab7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-05-04  Florian Weimer  <fweimer@redhat.com>
+
+	* inet/getnameinfo.c (gni_host_inet_name): Use temporaries to
+	avoid long lines.
+	(gni_host_inet_numeric): Likewise.  Reduce scope of local
+	variables.
+	(gni_host_inet, gni_host_local): Add comment.
+	(gni_host): Add comment.  Use temporary to avoid long lines.
+
 2016-05-04  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power8/strncpy.S: Fix use of condition
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index ce05dda..c649c49 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -198,10 +198,9 @@ gni_host_inet_name (struct scratch_buffer *tmpbuf,
   struct hostent *h = NULL;
   if (sa->sa_family == AF_INET6)
     {
-      while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr),
-				sizeof(struct in6_addr),
-				AF_INET6, &th,
-				tmpbuf->data, tmpbuf->length,
+      const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa;
+      while (__gethostbyaddr_r (&sin6p->sin6_addr, sizeof(struct in6_addr),
+				AF_INET6, &th, tmpbuf->data, tmpbuf->length,
 				&h, &herrno))
 	if (herrno == NETDB_INTERNAL && errno == ERANGE)
 	  {
@@ -216,10 +215,9 @@ gni_host_inet_name (struct scratch_buffer *tmpbuf,
     }
   else
     {
-      while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
-				sizeof(struct in_addr),
-				AF_INET, &th,
-				tmpbuf->data, tmpbuf->length,
+      const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
+      while (__gethostbyaddr_r (&sinp->sin_addr, sizeof(struct in_addr),
+				AF_INET, &th, tmpbuf->data, tmpbuf->length,
 				&h, &herrno))
 	if (herrno == NETDB_INTERNAL && errno == ERANGE)
 	    {
@@ -308,14 +306,10 @@ gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
   const char *c;
   if (sa->sa_family == AF_INET6)
     {
-      const struct sockaddr_in6 *sin6p;
-      uint32_t scopeid;
-
-      sin6p = (const struct sockaddr_in6 *) sa;
-
+      const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa;
       c = inet_ntop (AF_INET6,
 		     (const void *) &sin6p->sin6_addr, host, hostlen);
-      scopeid = sin6p->sin6_scope_id;
+      uint32_t scopeid = sin6p->sin6_scope_id;
       if (scopeid != 0)
 	{
 	  /* Buffer is >= IFNAMSIZ+1.  */
@@ -356,14 +350,16 @@ gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
 	}
     }
   else
-    c = inet_ntop (AF_INET,
-		   (const void *) &(((const struct sockaddr_in *) sa)->sin_addr),
-		   host, hostlen);
+    {
+      const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
+      c = inet_ntop (AF_INET, &sinp->sin_addr, host, hostlen);
+    }
   if (c == NULL)
     return EAI_OVERFLOW;
   return 0;
 }
 
+/* Convert AF_INET or AF_INET6 socket address, host part.  */
 static int
 gni_host_inet (struct scratch_buffer *tmpbuf,
 	       const struct sockaddr *sa, socklen_t addrlen,
@@ -384,6 +380,7 @@ gni_host_inet (struct scratch_buffer *tmpbuf,
       (tmpbuf, sa, addrlen, host, hostlen, flags);
 }
 
+/* Convert AF_LOCAL socket address, host part.   */
 static int
 gni_host_local (struct scratch_buffer *tmpbuf,
 		const struct sockaddr *sa, socklen_t addrlen,
@@ -408,6 +405,7 @@ gni_host_local (struct scratch_buffer *tmpbuf,
   return 0;
 }
 
+/* Convert the host part of an AF_LOCAK socket address.   */
 static int
 gni_host (struct scratch_buffer *tmpbuf,
 	  const struct sockaddr *sa, socklen_t addrlen,
@@ -439,11 +437,12 @@ gni_serv_inet (struct scratch_buffer *tmpbuf,
      && sizeof (((struct sockaddr_in) {}).sin_port) == sizeof (in_port_t)
      && sizeof (((struct sockaddr_in6) {}).sin6_port) == sizeof (in_port_t),
      "AF_INET and AF_INET6 port consistency");
+  const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
   if (!(flags & NI_NUMERICSERV))
     {
       struct servent *s, ts;
       int e;
-      while ((e = __getservbyport_r (((const struct sockaddr_in *) sa)->sin_port,
+      while ((e = __getservbyport_r (sinp->sin_port,
 				     ((flags & NI_DGRAM)
 				      ? "udp" : "tcp"), &ts,
 				     tmpbuf->data, tmpbuf->length, &s)))
@@ -463,9 +462,7 @@ gni_serv_inet (struct scratch_buffer *tmpbuf,
 	}
       /* Fall through to numeric conversion.  */
     }
-  if (__snprintf (serv, servlen, "%d",
-		  ntohs (((const struct sockaddr_in *) sa)->sin_port))
-      + 1 > servlen)
+  if (__snprintf (serv, servlen, "%d", ntohs (sinp->sin_port)) + 1 > servlen)
       return EAI_OVERFLOW;
   return 0;
 }

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

Summary of changes:
 ChangeLog          |   26 +++++++++
 inet/getnameinfo.c |  147 +++++++++++++++++++++++++---------------------------
 2 files changed, 97 insertions(+), 76 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]