From 2683e267fa6c20d2e7a498a85f79a1dfc4301f23 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 26 Oct 2015 18:42:22 -0400 Subject: safely handle failure to open hosts, services, resolv.conf files previously, transient failures like fd exhaustion or other resource-related errors were treated the same as non-existence of these files, leading to fallbacks or false-negative results. in particular: - failure to open hosts resulted in fallback to dns, possibly yielding EAI_NONAME for a hostname that should be defined locally, or an unwanted result from dns that the hosts file was intended to replace. - failure to open services resulted in EAI_SERVICE. - failure to open resolv.conf resulted in querying localhost rather than the configured nameservers. now, only permanent errors trigger the fallback behaviors above; all other errors are reportable to the caller as EAI_SYSTEM. --- src/network/res_msend.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/network/res_msend.c') diff --git a/src/network/res_msend.c b/src/network/res_msend.c index 35f106dd..d0e8e481 100644 --- a/src/network/res_msend.c +++ b/src/network/res_msend.c @@ -54,7 +54,15 @@ int __res_msend(int nqueries, const unsigned char *const *queries, /* Get nameservers from resolv.conf, fallback to localhost */ f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf); - if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) { + if (!f) switch (errno) { + case ENOENT: + case ENOTDIR: + case EACCES: + goto no_resolv_conf; + default: + return -1; + } + for (nns=0; nns<3 && fgets(line, sizeof line, f); ) { if (!strncmp(line, "options", 7) && isspace(line[7])) { unsigned long x; char *p, *z; @@ -92,7 +100,8 @@ int __res_msend(int nqueries, const unsigned char *const *queries, } } } - if (f) __fclose_ca(f); + __fclose_ca(f); +no_resolv_conf: if (!nns) { ns[0].sin.sin_family = AF_INET; ns[0].sin.sin_port = htons(53); -- cgit 1.4.1