aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2014-05-08 16:53:01 +0200
committerAndreas Schwab <schwab@suse.de>2014-05-12 15:17:51 +0200
commit315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c (patch)
tree95e476e2d0ce5885684e619ddbcb5996241f4c94
parent91df99f7f25d7b63ba36d54e41bc33ac6901f22d (diff)
downloadglibc-315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c.tar
glibc-315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c.tar.gz
glibc-315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c.tar.bz2
glibc-315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c.zip
Fix unbound stack use in NIS NSS module
-rw-r--r--ChangeLog11
-rw-r--r--NEWS2
-rw-r--r--nis/nss_nis/nis-hosts.c14
-rw-r--r--nis/nss_nis/nis-initgroups.c7
-rw-r--r--nis/nss_nis/nis-network.c7
-rw-r--r--nis/nss_nis/nis-service.c14
6 files changed, 54 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 2de2dd2205..babeb16f66 100644
--- 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 0a2b04f963..f06e33524c 100644
--- 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.
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index 462176ea03..d6192b1c77 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -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;
diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c
index e8fcca1bb1..9542faea48 100644
--- a/nis/nss_nis/nis-initgroups.c
+++ b/nis/nss_nis/nis-initgroups.c
@@ -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)];
diff --git a/nis/nss_nis/nis-network.c b/nis/nss_nis/nis-network.c
index f28fbdaa4f..f1b72bcd75 100644
--- a/nis/nss_nis/nis-network.c
+++ b/nis/nss_nis/nis-network.c
@@ -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;
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index f9b4a86d76..44e4e13f86 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -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" */