summaryrefslogtreecommitdiff
path: root/src/nss-resolve
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-07-15 23:00:00 +0900
committerLennart Poettering <lennart@poettering.net>2018-07-25 10:23:22 +0200
commit06202b9e659e5cc72aeecc5200155b7c012fccbc (patch)
tree7a22eef18632b21c764e1d446a21b8a3054f326b /src/nss-resolve
parent8d455017eedfe7e67f7fa5db9939c35b9e4dcf60 (diff)
downloadsystemd-06202b9e659e5cc72aeecc5200155b7c012fccbc.tar.gz
nss: do not modify errno when NSS_STATUS_NOTFOUND or NSS_STATUS_SUCCESS
This also adds PROTECT_ERRNO for all nss module functions. C.f. glibc NSS documents https://www.gnu.org/software/libc/manual/html_node/NSS-Modules-Interface.html and discussion in https://sourceware.org/bugzilla/show_bug.cgi?id=23410. Fixes #9585.
Diffstat (limited to 'src/nss-resolve')
-rw-r--r--src/nss-resolve/nss-resolve.c87
1 files changed, 39 insertions, 48 deletions
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
index eb3d2d977f..b2bb698ded 100644
--- a/src/nss-resolve/nss-resolve.c
+++ b/src/nss-resolve/nss-resolve.c
@@ -108,6 +108,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
char *r_name;
int c, r, i = 0;
+ PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
assert(name);
@@ -140,20 +141,15 @@ enum nss_status _nss_resolve_gethostbyname4_r(
r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
if (r < 0) {
- if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
- *errnop = ESRCH;
- *h_errnop = HOST_NOT_FOUND;
- return NSS_STATUS_NOTFOUND;
- }
+ if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
+ !bus_error_shall_fallback(&error))
+ goto not_found;
/* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails,
allowing falling back to other nss modules. Treat all other error conditions as
NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this
case so that the nsswitch.conf configuration can distuingish such executed but
negative replies from complete failure to talk to resolved). */
- if (!bus_error_shall_fallback(&error))
- ret = NSS_STATUS_NOTFOUND;
-
goto fail;
}
@@ -162,11 +158,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
r = c;
goto fail;
}
- if (c == 0) {
- *errnop = ESRCH;
- *h_errnop = HOST_NOT_FOUND;
- return NSS_STATUS_NOTFOUND;
- }
+ if (c == 0)
+ goto not_found;
if (isempty(canonical))
canonical = name;
@@ -247,8 +240,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
if (ttlp)
*ttlp = 0;
- /* Explicitly reset all error variables */
- *errnop = 0;
+ /* Explicitly reset both *h_errnop and h_errno to work around
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
*h_errnop = NETDB_SUCCESS;
h_errno = 0;
@@ -258,6 +251,10 @@ fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
return ret;
+
+not_found:
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
}
enum nss_status _nss_resolve_gethostbyname3_r(
@@ -278,6 +275,7 @@ enum nss_status _nss_resolve_gethostbyname3_r(
const char *canonical;
int c, r, i = 0;
+ PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
assert(name);
@@ -318,14 +316,9 @@ enum nss_status _nss_resolve_gethostbyname3_r(
r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
if (r < 0) {
- if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
- *errnop = ESRCH;
- *h_errnop = HOST_NOT_FOUND;
- return NSS_STATUS_NOTFOUND;
- }
-
- if (!bus_error_shall_fallback(&error))
- ret = NSS_STATUS_NOTFOUND;
+ if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
+ !bus_error_shall_fallback(&error))
+ goto not_found;
goto fail;
}
@@ -335,11 +328,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
r = c;
goto fail;
}
- if (c == 0) {
- *errnop = ESRCH;
- *h_errnop = HOST_NOT_FOUND;
- return NSS_STATUS_NOTFOUND;
- }
+ if (c == 0)
+ goto not_found;
if (isempty(canonical))
canonical = name;
@@ -427,23 +417,27 @@ enum nss_status _nss_resolve_gethostbyname3_r(
result->h_length = alen;
result->h_addr_list = (char**) r_addr_list;
- /* Explicitly reset all error variables */
- *errnop = 0;
- *h_errnop = NETDB_SUCCESS;
- h_errno = 0;
-
if (ttlp)
*ttlp = 0;
if (canonp)
*canonp = r_name;
+ /* Explicitly reset both *h_errnop and h_errno to work around
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
+ *h_errnop = NETDB_SUCCESS;
+ h_errno = 0;
+
return NSS_STATUS_SUCCESS;
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
return ret;
+
+not_found:
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
}
enum nss_status _nss_resolve_gethostbyaddr2_r(
@@ -464,6 +458,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
const char *n;
int r, ifindex;
+ PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
assert(addr);
@@ -516,14 +511,9 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
r = sd_bus_call(bus, req, SD_RESOLVED_QUERY_TIMEOUT_USEC, &error, &reply);
if (r < 0) {
- if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
- *errnop = ESRCH;
- *h_errnop = HOST_NOT_FOUND;
- return NSS_STATUS_NOTFOUND;
- }
-
- if (!bus_error_shall_fallback(&error))
- ret = NSS_STATUS_NOTFOUND;
+ if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN") ||
+ !bus_error_shall_fallback(&error))
+ goto not_found;
goto fail;
}
@@ -549,11 +539,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
if (r < 0)
return r;
- if (c <= 0) {
- *errnop = ESRCH;
- *h_errnop = HOST_NOT_FOUND;
- return NSS_STATUS_NOTFOUND;
- }
+ if (c <= 0)
+ goto not_found;
ms += ALIGN(len) + /* the address */
2 * sizeof(char*) + /* pointers to the address, plus trailing NULL */
@@ -612,8 +599,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
if (ttlp)
*ttlp = 0;
- /* Explicitly reset all error variables */
- *errnop = 0;
+ /* Explicitly reset both *h_errnop and h_errno to work around
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
*h_errnop = NETDB_SUCCESS;
h_errno = 0;
@@ -623,6 +610,10 @@ fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
return ret;
+
+not_found:
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
}
NSS_GETHOSTBYNAME_FALLBACKS(resolve);