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/lookup_serv.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/network/lookup_serv.c') diff --git a/src/network/lookup_serv.c b/src/network/lookup_serv.c index 4faa5bc7..66ebaea2 100644 --- a/src/network/lookup_serv.c +++ b/src/network/lookup_serv.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "lookup.h" #include "stdio_impl.h" @@ -69,7 +70,14 @@ int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int pro unsigned char _buf[1032]; FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf); - if (!f) return EAI_SERVICE; + if (!f) switch (errno) { + case ENOENT: + case ENOTDIR: + case EACCES: + return EAI_SERVICE; + default: + return EAI_SYSTEM; + } while (fgets(line, sizeof line, f) && cnt < MAXSERVS) { if ((p=strchr(line, '#'))) *p++='\n', *p=0; -- cgit v1.2.1