4c9df62
From fd0fb14e613f15a7d1fbde86bf371a72d8dfe3b8 Mon Sep 17 00:00:00 2001
4c9df62
From: Carlos O'Donell <carlos@systemhalted.org>
4c9df62
Date: Wed, 29 Nov 2017 22:36:39 -0800
4c9df62
Subject: [PATCH 75/79] nss: Fix invalid enum nss_status return values.
4c9df62
MIME-Version: 1.0
4c9df62
Content-Type: text/plain; charset=UTF-8
4c9df62
Content-Transfer-Encoding: 8bit
4c9df62
4c9df62
The upstream glibc test nss/bug17079 covers several cases where the
4c9df62
NSS infrastructure passes invalid pointers to NSS plugins. The plugins
4c9df62
should return correct results for the invalid values e.g. ERANGE,
4c9df62
but it should do so by setting *errnop to the error and returning
4c9df62
NSS_STATUS_TRYAGAIN. This commit fixes the group, netgroup, passwd
4c9df62
and service handling code to correctly return ERANGE in *errnop
4c9df62
and NSS_TATUS_TRYAGAIN in the case of invalid buffer (NULL) or
4c9df62
zero sized buffer length. This fixes the nss/bug17079 regression test
4c9df62
when run in a test configuration with sss enabled for any of the
4c9df62
above mentioned services.
4c9df62
4c9df62
Upstream glibc bug:
4c9df62
Bug 22530 - FAIL: nss/bug17079 due to _nss_sss_getpwuid_r
4c9df62
https://sourceware.org/bugzilla/show_bug.cgi?id=22530
4c9df62
4c9df62
Merges: https://pagure.io/SSSD/sssd/pull-request/3561
4c9df62
4c9df62
Signed-off-by: Carlos O'Donell <carlos@redhat.com>
4c9df62
Reviewed-by: Florian Weimer <fweimer@redhat.com>
4c9df62
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
4c9df62
---
4c9df62
 src/sss_client/nss_group.c    | 10 ++++++++--
4c9df62
 src/sss_client/nss_netgroup.c |  5 ++++-
4c9df62
 src/sss_client/nss_passwd.c   | 10 ++++++++--
4c9df62
 src/sss_client/nss_services.c | 15 ++++++++++++---
4c9df62
 4 files changed, 32 insertions(+), 8 deletions(-)
4c9df62
4c9df62
diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c
4c9df62
index 42fba6242d23fc1d52cfd7be10cf10383010f091..054f30e13f8d5f8300a3e63c9035b98d30473c0e 100644
4c9df62
--- a/src/sss_client/nss_group.c
4c9df62
+++ b/src/sss_client/nss_group.c
4c9df62
@@ -522,7 +522,10 @@ enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     ret = sss_nss_mc_getgrgid(gid, result, buffer, buflen);
4c9df62
     switch (ret) {
4c9df62
@@ -655,7 +658,10 @@ static enum nss_status internal_getgrent_r(struct group *result,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     /* if there are leftovers return the next one */
4c9df62
     if (sss_nss_getgrent_data.data != NULL &&
4c9df62
diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c
4c9df62
index 8594fc460514d6f92e786605168fa7d15c7ee913..3a1834a311e6658c6160b5f95a01434fed69ad1c 100644
4c9df62
--- a/src/sss_client/nss_netgroup.c
4c9df62
+++ b/src/sss_client/nss_netgroup.c
4c9df62
@@ -231,7 +231,10 @@ static enum nss_status internal_getnetgrent_r(struct __netgrent *result,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     /* If we're already processing result data, continue to
4c9df62
      * return it.
4c9df62
diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c
4c9df62
index 61e2a567e684fbc7664b5d425e81cfa28a98e845..5b1c2ce66b0954bc304dfb458f509defa8eed889 100644
4c9df62
--- a/src/sss_client/nss_passwd.c
4c9df62
+++ b/src/sss_client/nss_passwd.c
4c9df62
@@ -251,7 +251,10 @@ enum nss_status _nss_sss_getpwuid_r(uid_t uid, struct passwd *result,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     ret = sss_nss_mc_getpwuid(uid, result, buffer, buflen);
4c9df62
     switch (ret) {
4c9df62
@@ -376,7 +379,10 @@ static enum nss_status internal_getpwent_r(struct passwd *result,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     /* if there are leftovers return the next one */
4c9df62
     if (sss_nss_getpwent_data.data != NULL &&
4c9df62
diff --git a/src/sss_client/nss_services.c b/src/sss_client/nss_services.c
4c9df62
index 64e0b43e1643e4e76d2381a6b062335c3d513a21..161dad9ae27f822b40af8368e5af38b020d6549a 100644
4c9df62
--- a/src/sss_client/nss_services.c
4c9df62
+++ b/src/sss_client/nss_services.c
4c9df62
@@ -177,7 +177,10 @@ _nss_sss_getservbyname_r(const char *name,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
4c9df62
     if (ret != 0) {
4c9df62
@@ -278,7 +281,10 @@ _nss_sss_getservbyport_r(int port, const char *protocol,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     if (protocol) {
4c9df62
         ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len);
4c9df62
@@ -411,7 +417,10 @@ static enum nss_status internal_getservent_r(struct servent *result,
4c9df62
     int ret;
4c9df62
 
4c9df62
     /* Caught once glibc passing in buffer == 0x0 */
4c9df62
-    if (!buffer || !buflen) return ERANGE;
4c9df62
+    if (!buffer || !buflen) {
4c9df62
+	*errnop = ERANGE;
4c9df62
+	return NSS_STATUS_TRYAGAIN;
4c9df62
+    }
4c9df62
 
4c9df62
     /* if there are leftovers return the next one */
4c9df62
     if (sss_nss_getservent_data.data != NULL &&
4c9df62
-- 
4c9df62
2.15.1
4c9df62