Blame SOURCES/0123-nss-unportect-errno-before-writing-to-NSS-errnop.patch

a3e2b5
From ecc4a34067ed7c03b9ee710aa5e5976fded48c2a Mon Sep 17 00:00:00 2001
a3e2b5
From: Lennart Poettering <lennart@poettering.net>
a3e2b5
Date: Fri, 18 Jan 2019 20:13:55 +0100
a3e2b5
Subject: [PATCH] nss: unportect errno before writing to NSS' *errnop
a3e2b5
a3e2b5
Fixes: #11321
a3e2b5
(cherry picked from commit cdccd29f39cd20cb2a8b71e50445eb839f076331)
a3e2b5
a3e2b5
Resolves: #1691691
a3e2b5
---
a3e2b5
 src/nss-myhostname/nss-myhostname.c | 13 +++++++++++++
a3e2b5
 src/nss-mymachines/nss-mymachines.c | 13 +++++++++++++
a3e2b5
 src/nss-resolve/nss-resolve.c       |  8 ++++++++
a3e2b5
 src/nss-systemd/nss-systemd.c       | 10 ++++++++++
a3e2b5
 4 files changed, 44 insertions(+)
a3e2b5
a3e2b5
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
a3e2b5
index 5abc0c91bf..e491351dee 100644
a3e2b5
--- a/src/nss-myhostname/nss-myhostname.c
a3e2b5
+++ b/src/nss-myhostname/nss-myhostname.c
a3e2b5
@@ -74,6 +74,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
a3e2b5
         } else {
a3e2b5
                 hn = gethostname_malloc();
a3e2b5
                 if (!hn) {
a3e2b5
+                        UNPROTECT_ERRNO;
a3e2b5
                         *errnop = ENOMEM;
a3e2b5
                         *h_errnop = NO_RECOVERY;
a3e2b5
                         return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -96,6 +97,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
a3e2b5
         l = strlen(canonical);
a3e2b5
         ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -186,6 +188,8 @@ static enum nss_status fill_in_hostent(
a3e2b5
         assert(errnop);
a3e2b5
         assert(h_errnop);
a3e2b5
 
a3e2b5
+        PROTECT_ERRNO;
a3e2b5
+
a3e2b5
         alen = FAMILY_ADDRESS_SIZE(af);
a3e2b5
 
a3e2b5
         for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++)
a3e2b5
@@ -202,6 +206,7 @@ static enum nss_status fill_in_hostent(
a3e2b5
                 (c > 0 ? c+1 : 2) * sizeof(char*);
a3e2b5
 
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -321,6 +326,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
a3e2b5
                 af = AF_INET;
a3e2b5
 
a3e2b5
         if (!IN_SET(af, AF_INET, AF_INET6)) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = EAFNOSUPPORT;
a3e2b5
                 *h_errnop = NO_DATA;
a3e2b5
                 return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -343,6 +349,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
a3e2b5
         } else {
a3e2b5
                 hn = gethostname_malloc();
a3e2b5
                 if (!hn) {
a3e2b5
+                        UNPROTECT_ERRNO;
a3e2b5
                         *errnop = ENOMEM;
a3e2b5
                         *h_errnop = NO_RECOVERY;
a3e2b5
                         return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -362,6 +369,8 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
a3e2b5
                 local_address_ipv4 = LOCALADDRESS_IPV4;
a3e2b5
         }
a3e2b5
 
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
+
a3e2b5
         return fill_in_hostent(
a3e2b5
                         canonical, additional,
a3e2b5
                         af,
a3e2b5
@@ -401,12 +410,14 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
a3e2b5
         assert(h_errnop);
a3e2b5
 
a3e2b5
         if (!IN_SET(af, AF_INET, AF_INET6)) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = EAFNOSUPPORT;
a3e2b5
                 *h_errnop = NO_DATA;
a3e2b5
                 return NSS_STATUS_UNAVAIL;
a3e2b5
         }
a3e2b5
 
a3e2b5
         if (len != FAMILY_ADDRESS_SIZE(af)) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = EINVAL;
a3e2b5
                 *h_errnop = NO_RECOVERY;
a3e2b5
                 return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -461,6 +472,7 @@ found:
a3e2b5
         if (!canonical || additional_from_hostname) {
a3e2b5
                 hn = gethostname_malloc();
a3e2b5
                 if (!hn) {
a3e2b5
+                        UNPROTECT_ERRNO;
a3e2b5
                         *errnop = ENOMEM;
a3e2b5
                         *h_errnop = NO_RECOVERY;
a3e2b5
                         return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -472,6 +484,7 @@ found:
a3e2b5
                         additional = hn;
a3e2b5
         }
a3e2b5
 
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         return fill_in_hostent(
a3e2b5
                         canonical, additional,
a3e2b5
                         af,
a3e2b5
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
a3e2b5
index 9b81cd9ad1..af9f0bf41f 100644
a3e2b5
--- a/src/nss-mymachines/nss-mymachines.c
a3e2b5
+++ b/src/nss-mymachines/nss-mymachines.c
a3e2b5
@@ -134,6 +134,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
a3e2b5
         l = strlen(name);
a3e2b5
         ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -208,6 +209,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_DATA;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -289,6 +291,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
a3e2b5
         ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
a3e2b5
 
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -372,6 +375,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_DATA;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -455,6 +459,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
 
a3e2b5
         l = strlen(name);
a3e2b5
         if (buflen < l+1) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -472,6 +477,7 @@ enum nss_status _nss_mymachines_getpwnam_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -530,6 +536,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
a3e2b5
                 return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -545,6 +552,7 @@ enum nss_status _nss_mymachines_getpwuid_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -623,6 +631,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
 
a3e2b5
         l = sizeof(char*) + strlen(name) + 1;
a3e2b5
         if (buflen < l) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -638,6 +647,7 @@ enum nss_status _nss_mymachines_getgrnam_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -696,12 +706,14 @@ enum nss_status _nss_mymachines_getgrgid_r(
a3e2b5
                 return NSS_STATUS_NOTFOUND;
a3e2b5
 
a3e2b5
         if (buflen < sizeof(char*) + 1) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
 
a3e2b5
         memzero(buffer, sizeof(char*));
a3e2b5
         if (snprintf(buffer + sizeof(char*), buflen - sizeof(char*), "vg-%s-" GID_FMT, machine, (gid_t) mapped) >= (int) buflen) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -714,6 +726,7 @@ enum nss_status _nss_mymachines_getgrgid_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
a3e2b5
index b2bb698ded..145dbdd60c 100644
a3e2b5
--- a/src/nss-resolve/nss-resolve.c
a3e2b5
+++ b/src/nss-resolve/nss-resolve.c
a3e2b5
@@ -167,6 +167,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
a3e2b5
         l = strlen(canonical);
a3e2b5
         ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -248,6 +249,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_RECOVERY;
a3e2b5
         return ret;
a3e2b5
@@ -340,6 +342,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
         ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
a3e2b5
 
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -431,6 +434,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_RECOVERY;
a3e2b5
         return ret;
a3e2b5
@@ -468,12 +472,14 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
         assert(h_errnop);
a3e2b5
 
a3e2b5
         if (!IN_SET(af, AF_INET, AF_INET6)) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = EAFNOSUPPORT;
a3e2b5
                 *h_errnop = NO_DATA;
a3e2b5
                 return NSS_STATUS_UNAVAIL;
a3e2b5
         }
a3e2b5
 
a3e2b5
         if (len != FAMILY_ADDRESS_SIZE(af)) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = EINVAL;
a3e2b5
                 *h_errnop = NO_RECOVERY;
a3e2b5
                 return NSS_STATUS_UNAVAIL;
a3e2b5
@@ -547,6 +553,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
               c * sizeof(char*);        /* pointers to aliases, plus trailing NULL */
a3e2b5
 
a3e2b5
         if (buflen < ms) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 *h_errnop = NETDB_INTERNAL;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
@@ -607,6 +614,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         *h_errnop = NO_RECOVERY;
a3e2b5
         return ret;
a3e2b5
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
a3e2b5
index f554828d49..f8db27ae27 100644
a3e2b5
--- a/src/nss-systemd/nss-systemd.c
a3e2b5
+++ b/src/nss-systemd/nss-systemd.c
a3e2b5
@@ -210,6 +210,7 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
 
a3e2b5
         l = strlen(name);
a3e2b5
         if (buflen < l+1) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -227,6 +228,7 @@ enum nss_status _nss_systemd_getpwnam_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -310,6 +312,7 @@ enum nss_status _nss_systemd_getpwuid_r(
a3e2b5
 
a3e2b5
         l = strlen(translated) + 1;
a3e2b5
         if (buflen < l) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -327,6 +330,7 @@ enum nss_status _nss_systemd_getpwuid_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -408,6 +412,7 @@ enum nss_status _nss_systemd_getgrnam_r(
a3e2b5
 
a3e2b5
         l = sizeof(char*) + strlen(name) + 1;
a3e2b5
         if (buflen < l) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -423,6 +428,7 @@ enum nss_status _nss_systemd_getgrnam_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -506,6 +512,7 @@ enum nss_status _nss_systemd_getgrgid_r(
a3e2b5
 
a3e2b5
         l = sizeof(char*) + strlen(translated) + 1;
a3e2b5
         if (buflen < l) {
a3e2b5
+                UNPROTECT_ERRNO;
a3e2b5
                 *errnop = ERANGE;
a3e2b5
                 return NSS_STATUS_TRYAGAIN;
a3e2b5
         }
a3e2b5
@@ -521,6 +528,7 @@ enum nss_status _nss_systemd_getgrgid_r(
a3e2b5
         return NSS_STATUS_SUCCESS;
a3e2b5
 
a3e2b5
 fail:
a3e2b5
+        UNPROTECT_ERRNO;
a3e2b5
         *errnop = -r;
a3e2b5
         return NSS_STATUS_UNAVAIL;
a3e2b5
 }
a3e2b5
@@ -740,6 +748,7 @@ enum nss_status _nss_systemd_getpwent_r(struct passwd *result, char *buffer, siz
a3e2b5
         LIST_FOREACH(entries, p, getpwent_data.position) {
a3e2b5
                 len = strlen(p->name) + 1;
a3e2b5
                 if (buflen < len) {
a3e2b5
+                        UNPROTECT_ERRNO;
a3e2b5
                         *errnop = ERANGE;
a3e2b5
                         ret = NSS_STATUS_TRYAGAIN;
a3e2b5
                         goto finalize;
a3e2b5
@@ -791,6 +800,7 @@ enum nss_status _nss_systemd_getgrent_r(struct group *result, char *buffer, size
a3e2b5
         LIST_FOREACH(entries, p, getgrent_data.position) {
a3e2b5
                 len = sizeof(char*) + strlen(p->name) + 1;
a3e2b5
                 if (buflen < len) {
a3e2b5
+                        UNPROTECT_ERRNO;
a3e2b5
                         *errnop = ERANGE;
a3e2b5
                         ret = NSS_STATUS_TRYAGAIN;
a3e2b5
                         goto finalize;