From 3a362d4a95b999f088a12df8dd0abccb66f11ca1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 14 Aug 2009 04:52:21 -0400 Subject: Catch possible bad input passed in by glibc Seen in tests and was leading to a segfault --- sss_client/group.c | 11 +++++++++++ sss_client/passwd.c | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/sss_client/group.c b/sss_client/group.c index 61b1e487b..675b8b71e 100644 --- a/sss_client/group.c +++ b/sss_client/group.c @@ -66,6 +66,8 @@ static void sss_nss_getgrent_data_clean(void) { * 0-3: 32bit number gid * 4-7: 32bit unsigned number of members * 8-X: sequence of 0 terminated strings (name, passwd, mem..) + * + * FIXME: do we need to pad so that each result is 32 bit aligned ? */ struct sss_nss_gr_rep { struct group *result; @@ -239,6 +241,9 @@ enum nss_status _nss_sss_getgrnam_r(const char *name, struct group *result, enum nss_status nret; int ret; + /* Caught once glibc passing in buffer == 0x0 */ + if (!buffer || !buflen) return ERANGE; + rd.len = strlen(name) + 1; rd.data = name; @@ -286,6 +291,9 @@ enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result, uint32_t group_gid; int ret; + /* Caught once glibc passing in buffer == 0x0 */ + if (!buffer || !buflen) return ERANGE; + group_gid = gid; rd.len = sizeof(uint32_t); rd.data = &group_gid; @@ -352,6 +360,9 @@ enum nss_status _nss_sss_getgrent_r(struct group *result, uint32_t num_entries; int ret; + /* Caught once glibc passing in buffer == 0x0 */ + if (!buffer || !buflen) return ERANGE; + /* if there are leftovers return the next one */ if (sss_nss_getgrent_data.data != NULL && sss_nss_getgrent_data.ptr < sss_nss_getgrent_data.len) { diff --git a/sss_client/passwd.c b/sss_client/passwd.c index e999e5dd5..0d70b6843 100644 --- a/sss_client/passwd.c +++ b/sss_client/passwd.c @@ -180,6 +180,9 @@ enum nss_status _nss_sss_getpwnam_r(const char *name, struct passwd *result, enum nss_status nret; int ret; + /* Caught once glibc passing in buffer == 0x0 */ + if (!buffer || !buflen) return ERANGE; + rd.len = strlen(name) + 1; rd.data = name; @@ -227,6 +230,9 @@ enum nss_status _nss_sss_getpwuid_r(uid_t uid, struct passwd *result, uint32_t user_uid; int ret; + /* Caught once glibc passing in buffer == 0x0 */ + if (!buffer || !buflen) return ERANGE; + user_uid = uid; rd.len = sizeof(uint32_t); rd.data = &user_uid; @@ -294,6 +300,9 @@ enum nss_status _nss_sss_getpwent_r(struct passwd *result, uint32_t num_entries; int ret; + /* Caught once glibc passing in buffer == 0x0 */ + if (!buffer || !buflen) return ERANGE; + /* if there are leftovers return the next one */ if (sss_nss_getpwent_data.data != NULL && sss_nss_getpwent_data.ptr < sss_nss_getpwent_data.len) { -- cgit