From 968b59ad2aecdbe67ac5016c395a7e38fd682bb7 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 8 May 2014 16:53:01 +0200 Subject: Fix unbound stack use in NIS NSS module (cherry picked from commit 315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c) Conflicts: NEWS --- ChangeLog | 11 +++++++++++ NEWS | 2 +- nis/nss_nis/nis-hosts.c | 14 ++++++++++++++ nis/nss_nis/nis-initgroups.c | 7 +++++++ nis/nss_nis/nis-network.c | 7 +++++++ nis/nss_nis/nis-service.c | 14 ++++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cbabc37eb5..09056daded 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-05-12 Andreas Schwab + + [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-06-21 Allan McRae * NEWS: Mention CVE-2014-4043. diff --git a/NEWS b/NEWS index 4a51ac6b9a..d10a3aa442 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,7 @@ Version 2.19.1 * The following bugs are resolved with this release: - 16545, 16623, 16882, 16885, 16916, 16943, 16958, 17048. + 16545, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048. * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not copy the path argument. This allowed programs to cause posix_spawn to diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c index f73a0eccb2..3006a997ab 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 30bc90f691..dd8c765200 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 da28860003..6a823024f9 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 fd79d3fe07..4991ed3342 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" */ -- cgit 1.4.1