]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix unbound stack use in NIS NSS module
authorAndreas Schwab <schwab@suse.de>
Thu, 8 May 2014 14:53:01 +0000 (16:53 +0200)
committerAndreas Schwab <schwab@suse.de>
Mon, 12 May 2014 13:17:51 +0000 (15:17 +0200)
ChangeLog
NEWS
nis/nss_nis/nis-hosts.c
nis/nss_nis/nis-initgroups.c
nis/nss_nis/nis-network.c
nis/nss_nis/nis-service.c

index 2de2dd2205394cfe07d69e7ee48737f30444abd1..babeb16f66fb9a93a3b9721249b7042ccf2c3a30 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-05-12  Andreas Schwab  <schwab@suse.de>
+
+       [BZ #16932]
+       * nis/nss_nis/nis-hosts.c (internal_gethostbyname2_r)
+       (_nss_nis_gethostbyname4_r): Return error if item length is larger
+       than maximum RPC packet size.
+       * nis/nss_nis/nis-initgroups.c (initgroups_netid): Likewise.
+       * nis/nss_nis/nis-network.c (_nss_nis_getnetbyname_r): Likewise.
+       * nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r)
+       (_nss_nis_getservbyport_r): Likewise.
+
 2014-05-12  Will Newton  <will.newton@linaro.org>
 
        * malloc/Makefile (tests): Add tst-mallopt.
diff --git a/NEWS b/NEWS
index 0a2b04f9638da658df6adff507a243b699b7b961..f06e33524cb30d58785e089f3197f9c9d89a96bb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,7 @@ Version 2.20
   16677, 16680, 16683, 16689, 16695, 16701, 16706, 16707, 16712, 16713,
   16714, 16731, 16739, 16740, 16743, 16754, 16758, 16759, 16760, 16770,
   16786, 16789, 16791, 16799, 16800, 16815, 16823, 16824, 16831, 16838,
-  16854, 16876, 16877, 16885, 16888, 16890, 16912, 16916, 16922.
+  16854, 16876, 16877, 16885, 16888, 16890, 16912, 16916, 16922, 16932.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
index 462176ea03cbb37e2da69a3f2d1d153a1df46ec9..d6192b1c771daad098be7f90cc338f6fc2551fbc 100644 (file)
@@ -270,6 +270,13 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
@@ -461,6 +468,13 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
index e8fcca1bb14689e85d78a68bafaf475244b6ca29..9542faea48b72a0c2933b9178fec35dd0104eb2d 100644 (file)
@@ -150,6 +150,13 @@ initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
                  gid_t **groupsp, long int limit, int *errnop,
                  const char *domainname)
 {
+  /* Limit domainname length to the maximum size of an RPC packet.  */
+  if (strlen (domainname) > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   /* Prepare the key.  The form is "unix.UID@DOMAIN" with the UID and
      DOMAIN field filled in appropriately.  */
   char key[sizeof ("unix.@") + sizeof (uid_t) * 3 + strlen (domainname)];
index f28fbdaa4f8934d3199b144446579ad53bea9dbb..f1b72bcd7599eea62e839a202ee3f43fecac7ecf 100644 (file)
@@ -179,6 +179,13 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
index f9b4a86d764712499a2f9b2d1499fbbda76814e1..44e4e13f8699867cdab42ca9747887642e526f4f 100644 (file)
@@ -271,6 +271,13 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol,
   /* If the protocol is given, we could try if our NIS server knows
      about services.byservicename map. If yes, we only need one query.  */
   size_t keylen = strlen (name) + (protocol ? 1 + strlen (protocol) : 0);
+  /* Limit key length to the maximum size of an RPC packet.  */
+  if (keylen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char key[keylen + 1];
 
   /* key is: "name/proto" */
@@ -355,6 +362,13 @@ _nss_nis_getservbyport_r (int port, const char *protocol,
      Otherwise try first port/tcp, then port/udp and then fallback
      to sequential scanning of services.byname.  */
   const char *proto = protocol != NULL ? protocol : "tcp";
+  /* Limit protocol name length to the maximum size of an RPC packet.  */
+  if (strlen (proto) > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   do
     {
       /* key is: "port/proto" */