When no gethostbyname*_r lookup functions can be loaded from a module (most commonly when a module is listed in /etc/nsswitch.conf that does not exist), gaih_inet falls into this block added in revision 3d04f5db20c8f0d1ba3881b5f5373586a18cf188 for #15339: if (errno != 0 && errno != ENOENT) __set_h_errno (NETDB_INTERNAL); but there is no guarantee that errno was set - it's not set by __nss_lookup_function, and other previous lookup functions don't have to set it. This is problem #1. Problem #2 is lower down: if (h_errno == NETDB_INTERNAL) { result = -EAI_SYSTEM; goto free_and_return; } this time there's no guarantee that h_errno is set, so it probably still has the same value as the last call to gaih_inet. To reproduce: $ grep hosts /etc/nsswitch.conf hosts: files dns doesnotexist $ cat test.c #include <netdb.h> #include <stdio.h> #include <errno.h> #include <unistd.h> void gai(const char* addr) { struct addrinfo* res; int ret = getaddrinfo(addr, "80", NULL, &res); if (ret != 0) { printf("\"%s\" failed: %d, errno=%d\n", addr, ret, errno); } else { printf("\"%s\" succeeded\n", addr); freeaddrinfo(res); } } int main(int argc, char** argv) { char hostname[1024]; gethostname(hostname, sizeof(hostname) - 1); gai(hostname); /* Returns 0. */ errno = EAGAIN; gai("does.not.resolve"); /* Returns EAI_SYSTEM, should return EAI_NONAME. */ gai(hostname); /* Returns EAI_SYSTEM, should return 0. */ return 0; } Output: $ gcc -o test test.c && ./test "[my hostname]" succeeded "does.not.resolve" failed: -11, errno=11 "[my hostname]" failed: -11, errno=11 Expected: $ gcc -o test test.c && ./test "[my hostname]" succeeded "does.not.resolve" failed: -2, errno=11 "[my hostname]" succeeded I'm not sure how to fix this because I'm not sure what errors revision 3d04f5db20c8f0d1ba3881b5f5373586a18cf188 is trying to catch. Errors loading nss modules don't seem to be reported through errno (and I think everything's cached after the first call anyway?). Maybe we should clear errno at the start of gaih_inet, but #19445 says we should reset it again before we exit.
Is this related to these mailing list threads? https://sourceware.org/ml/libc-alpha/2016-07/msg00341.html https://sourceware.org/ml/libc-alpha/2016-07/msg00618.html
(In reply to Florian Weimer from comment #1) > Is this related to these mailing list threads? > > https://sourceware.org/ml/libc-alpha/2016-07/msg00341.html > https://sourceware.org/ml/libc-alpha/2016-07/msg00618.html That is problem #2. Problem #1 is different and may just be a matter of resetting errno before trying callbacks.
Note that gethosts is also buggy in this regard: while (1) { \ rc = 0; \ status = DL_CALL_FCT (fct, (name, _family, &th, \ tmpbuf->data, tmpbuf->length, \ &rc, &herrno, NULL, &localcanon)); \ if (rc != ERANGE || herrno != NETDB_INTERNAL) \ break; \ if (!scratch_buffer_grow (tmpbuf)) \ { \ result = -EAI_MEMORY; \ goto free_and_return; \ } \ } \ if (status == NSS_STATUS_SUCCESS && rc == 0) \ h = &th; \ else \ h = NULL; \ if (rc != 0) \ It assumes that rc (essentially errno) and herrno are valid for all status return values. In reality, at least nss_files can return NSS_STATUS_SUCCESS with clobbered errno and h_errno values.
I filed bug 21915 for the issue raised in comment 3.
Problem #1 should be fixed by this commit: commit ad816a5e00ce891a2cea8187638fa0e00f83aaf6 Author: Florian Weimer <fweimer@redhat.com> Date: Fri Sep 1 08:57:28 2017 +0200 getaddrinfo: Properly set errno for NSS function lookup failure
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU C Library master sources". The branch, master has been updated via 63b52889c35b367cf20896442203bbe5d123058c (commit) from 9a08a366a7e7ddffe62113a9ffe5e50605ea0924 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=63b52889c35b367cf20896442203bbe5d123058c commit 63b52889c35b367cf20896442203bbe5d123058c Author: Florian Weimer <fweimer@redhat.com> Date: Fri Jan 12 12:15:38 2018 +0100 Add missing reference to bug 20532 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU C Library master sources". The branch, release/2.26/master has been updated via 7d2672a47b24c6991ddbcc7b65a5086caed4596a (commit) from 268bd5f053204b80e771169e55b45704c04d77ad (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=7d2672a47b24c6991ddbcc7b65a5086caed4596a commit 7d2672a47b24c6991ddbcc7b65a5086caed4596a Author: Florian Weimer <fweimer@redhat.com> Date: Fri Jan 12 13:32:51 2018 +0100 Add missing reference to bug 20532 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 1 + NEWS | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)