From 22c7230dc0c8d41a189eb758be78991d183de1f7 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Fri, 6 Jan 2012 13:56:34 -0500 Subject: NSS: Validate input string lengths Also fixes a return value bug where we were returning errno error codes instead of nss_status codes. Fixes https://fedorahosted.org/sssd/ticket/1135 --- src/sss_client/nss_group.c | 15 ++++++++++++--- src/sss_client/nss_netgroup.c | 4 +--- src/sss_client/nss_passwd.c | 15 ++++++++++++--- src/sss_client/sss_cli.h | 7 +++++++ 4 files changed, 32 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c index 9e308c929..f5e715c86 100644 --- a/src/sss_client/nss_group.c +++ b/src/sss_client/nss_group.c @@ -254,14 +254,23 @@ enum nss_status _nss_sss_getgrnam_r(const char *name, struct group *result, struct sss_cli_req_data rd; struct sss_nss_gr_rep grrep; uint8_t *repbuf; - size_t replen, len; + size_t replen, len, name_len; enum nss_status nret; int ret; /* Caught once glibc passing in buffer == 0x0 */ - if (!buffer || !buflen) return ERANGE; + if (!buffer || !buflen) { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + ret = sss_strnlen(name, SSS_NAME_MAX, &name_len); + if (ret != 0) { + *errnop = EINVAL; + return NSS_STATUS_NOTFOUND; + } - rd.len = strlen(name) + 1; + rd.len = name_len + 1; rd.data = name; sss_nss_lock(); diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c index 2d1acc5df..f63b11359 100644 --- a/src/sss_client/nss_netgroup.c +++ b/src/sss_client/nss_netgroup.c @@ -33,8 +33,6 @@ #include "sss_cli.h" #include "nss_compat.h" -#define MAX_NETGR_NAME_LENGTH 2048 - #define CLEAR_NETGRENT_DATA(netgrent) do { \ free(netgrent->data); \ netgrent->data = NULL; \ @@ -201,7 +199,7 @@ enum nss_status _nss_sss_setnetgrent(const char *netgroup, /* make sure we do not have leftovers, and release memory */ CLEAR_NETGRENT_DATA(result); - ret = sss_strnlen(netgroup, MAX_NETGR_NAME_LENGTH, &name_len); + ret = sss_strnlen(netgroup, SSS_NAME_MAX, &name_len); if (ret != 0) { nret = NSS_STATUS_NOTFOUND; goto out; diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c index 31b9a7949..15de59728 100644 --- a/src/sss_client/nss_passwd.c +++ b/src/sss_client/nss_passwd.c @@ -179,14 +179,23 @@ enum nss_status _nss_sss_getpwnam_r(const char *name, struct passwd *result, struct sss_cli_req_data rd; struct sss_nss_pw_rep pwrep; uint8_t *repbuf; - size_t replen, len; + size_t replen, len, name_len; enum nss_status nret; int ret; /* Caught once glibc passing in buffer == 0x0 */ - if (!buffer || !buflen) return ERANGE; + if (!buffer || !buflen) { + *errnop = ERANGE; + return NSS_STATUS_TRYAGAIN; + } + + ret = sss_strnlen(name, SSS_NAME_MAX, &name_len); + if (ret != 0) { + *errnop = EINVAL; + return NSS_STATUS_NOTFOUND; + } - rd.len = strlen(name) + 1; + rd.len = name_len + 1; rd.data = name; sss_nss_lock(); diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index f9bbda98e..dc15ac13b 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifndef HAVE_ERRNO_T #define HAVE_ERRNO_T @@ -39,6 +40,12 @@ typedef int errno_t; #define SSS_PAM_PROTOCOL_VERSION 3 #define SSS_SUDO_PROTOCOL_VERSION 0 +#ifdef LOGIN_NAME_MAX +#define SSS_NAME_MAX LOGIN_NAME_MAX +#else +#define SSS_NAME_MAX 256 +#endif + /** * @defgroup sss_cli_command SSS client commands * @{ -- cgit