diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2018-07-15 23:00:00 +0900 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-07-25 10:23:22 +0200 |
commit | 06202b9e659e5cc72aeecc5200155b7c012fccbc (patch) | |
tree | 7a22eef18632b21c764e1d446a21b8a3054f326b /src/nss-mymachines/nss-mymachines.c | |
parent | 8d455017eedfe7e67f7fa5db9939c35b9e4dcf60 (diff) | |
download | systemd-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-mymachines/nss-mymachines.c')
-rw-r--r-- | src/nss-mymachines/nss-mymachines.c | 88 |
1 files changed, 36 insertions, 52 deletions
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c index 8d6caa0ada..9b81cd9ad1 100644 --- a/src/nss-mymachines/nss-mymachines.c +++ b/src/nss-mymachines/nss-mymachines.c @@ -80,6 +80,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r( char *r_name; int n_ifindices, r; + PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); assert(name); @@ -126,7 +127,6 @@ enum nss_status _nss_mymachines_gethostbyname4_r( goto fail; if (c <= 0) { - *errnop = ESRCH; *h_errnop = HOST_NOT_FOUND; return NSS_STATUS_NOTFOUND; } @@ -200,8 +200,8 @@ enum nss_status _nss_mymachines_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; @@ -230,6 +230,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r( size_t l, idx, ms, alen; int r; + PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); assert(name); @@ -278,7 +279,6 @@ enum nss_status _nss_mymachines_gethostbyname3_r( goto fail; if (c <= 0) { - *errnop = ENOENT; *h_errnop = HOST_NOT_FOUND; return NSS_STATUS_NOTFOUND; } @@ -364,8 +364,8 @@ enum nss_status _nss_mymachines_gethostbyname3_r( if (canonp) *canonp = r_name; - /* 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; @@ -394,6 +394,7 @@ enum nss_status _nss_mymachines_getpwnam_r( size_t l; int r; + PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); assert(name); @@ -401,28 +402,28 @@ enum nss_status _nss_mymachines_getpwnam_r( p = startswith(name, "vu-"); if (!p) - goto not_found; + return NSS_STATUS_NOTFOUND; e = strrchr(p, '-'); if (!e || e == p) - goto not_found; + return NSS_STATUS_NOTFOUND; if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */ - goto not_found; + return NSS_STATUS_NOTFOUND; r = parse_uid(e + 1, &uid); if (r < 0) - goto not_found; + return NSS_STATUS_NOTFOUND; machine = strndupa(p, e - p); if (!machine_name_is_valid(machine)) - goto not_found; + return NSS_STATUS_NOTFOUND; if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) /* Make sure we can't deadlock if we are invoked by dbus-daemon. This way, it won't be able to resolve * these UIDs, but that should be unproblematic as containers should never be able to connect to a bus * running on the host. */ - goto not_found; + return NSS_STATUS_NOTFOUND; r = sd_bus_open_system(&bus); if (r < 0) @@ -439,7 +440,7 @@ enum nss_status _nss_mymachines_getpwnam_r( machine, (uint32_t) uid); if (r < 0) { if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING)) - goto not_found; + return NSS_STATUS_NOTFOUND; goto fail; } @@ -450,7 +451,7 @@ enum nss_status _nss_mymachines_getpwnam_r( /* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */ if (mapped < HOST_UID_LIMIT || mapped == uid) - goto not_found; + return NSS_STATUS_NOTFOUND; l = strlen(name); if (buflen < l+1) { @@ -468,13 +469,8 @@ enum nss_status _nss_mymachines_getpwnam_r( pwd->pw_dir = (char*) "/"; pwd->pw_shell = (char*) "/sbin/nologin"; - *errnop = 0; return NSS_STATUS_SUCCESS; -not_found: - *errnop = 0; - return NSS_STATUS_NOTFOUND; - fail: *errnop = -r; return NSS_STATUS_UNAVAIL; @@ -493,17 +489,18 @@ enum nss_status _nss_mymachines_getpwuid_r( uint32_t mapped; int r; + PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); if (!uid_is_valid(uid)) - goto not_found; + return NSS_STATUS_NOTFOUND; /* We consider all uids < 65536 host uids */ if (uid < HOST_UID_LIMIT) - goto not_found; + return NSS_STATUS_NOTFOUND; if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) - goto not_found; + return NSS_STATUS_NOTFOUND; r = sd_bus_open_system(&bus); if (r < 0) @@ -520,7 +517,7 @@ enum nss_status _nss_mymachines_getpwuid_r( (uint32_t) uid); if (r < 0) { if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING)) - goto not_found; + return NSS_STATUS_NOTFOUND; goto fail; } @@ -530,7 +527,7 @@ enum nss_status _nss_mymachines_getpwuid_r( goto fail; if (mapped == uid) - goto not_found; + return NSS_STATUS_NOTFOUND; if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) { *errnop = ERANGE; @@ -545,13 +542,8 @@ enum nss_status _nss_mymachines_getpwuid_r( pwd->pw_dir = (char*) "/"; pwd->pw_shell = (char*) "/sbin/nologin"; - *errnop = 0; return NSS_STATUS_SUCCESS; -not_found: - *errnop = 0; - return NSS_STATUS_NOTFOUND; - fail: *errnop = -r; return NSS_STATUS_UNAVAIL; @@ -574,6 +566,7 @@ enum nss_status _nss_mymachines_getgrnam_r( size_t l; int r; + PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); assert(name); @@ -581,25 +574,25 @@ enum nss_status _nss_mymachines_getgrnam_r( p = startswith(name, "vg-"); if (!p) - goto not_found; + return NSS_STATUS_NOTFOUND; e = strrchr(p, '-'); if (!e || e == p) - goto not_found; + return NSS_STATUS_NOTFOUND; if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */ - goto not_found; + return NSS_STATUS_NOTFOUND; r = parse_gid(e + 1, &gid); if (r < 0) - goto not_found; + return NSS_STATUS_NOTFOUND; machine = strndupa(p, e - p); if (!machine_name_is_valid(machine)) - goto not_found; + return NSS_STATUS_NOTFOUND; if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) - goto not_found; + return NSS_STATUS_NOTFOUND; r = sd_bus_open_system(&bus); if (r < 0) @@ -616,7 +609,7 @@ enum nss_status _nss_mymachines_getgrnam_r( machine, (uint32_t) gid); if (r < 0) { if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING)) - goto not_found; + return NSS_STATUS_NOTFOUND; goto fail; } @@ -626,7 +619,7 @@ enum nss_status _nss_mymachines_getgrnam_r( goto fail; if (mapped < HOST_GID_LIMIT || mapped == gid) - goto not_found; + return NSS_STATUS_NOTFOUND; l = sizeof(char*) + strlen(name) + 1; if (buflen < l) { @@ -642,13 +635,8 @@ enum nss_status _nss_mymachines_getgrnam_r( gr->gr_passwd = (char*) "*"; /* locked */ gr->gr_mem = (char**) buffer; - *errnop = 0; return NSS_STATUS_SUCCESS; -not_found: - *errnop = 0; - return NSS_STATUS_NOTFOUND; - fail: *errnop = -r; return NSS_STATUS_UNAVAIL; @@ -667,17 +655,18 @@ enum nss_status _nss_mymachines_getgrgid_r( uint32_t mapped; int r; + PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); if (!gid_is_valid(gid)) - goto not_found; + return NSS_STATUS_NOTFOUND; /* We consider all gids < 65536 host gids */ if (gid < HOST_GID_LIMIT) - goto not_found; + return NSS_STATUS_NOTFOUND; if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_BUS") > 0) - goto not_found; + return NSS_STATUS_NOTFOUND; r = sd_bus_open_system(&bus); if (r < 0) @@ -694,7 +683,7 @@ enum nss_status _nss_mymachines_getgrgid_r( (uint32_t) gid); if (r < 0) { if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING)) - goto not_found; + return NSS_STATUS_NOTFOUND; goto fail; } @@ -704,7 +693,7 @@ enum nss_status _nss_mymachines_getgrgid_r( goto fail; if (mapped == gid) - goto not_found; + return NSS_STATUS_NOTFOUND; if (buflen < sizeof(char*) + 1) { *errnop = ERANGE; @@ -722,13 +711,8 @@ enum nss_status _nss_mymachines_getgrgid_r( gr->gr_passwd = (char*) "*"; /* locked */ gr->gr_mem = (char**) buffer; - *errnop = 0; return NSS_STATUS_SUCCESS; -not_found: - *errnop = 0; - return NSS_STATUS_NOTFOUND; - fail: *errnop = -r; return NSS_STATUS_UNAVAIL; |