about summary refs log tree commit diff
path: root/src/network/lookup_name.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-10-26 18:42:22 -0400
committerRich Felker <dalias@aerifal.cx>2015-10-26 18:42:22 -0400
commit2683e267fa6c20d2e7a498a85f79a1dfc4301f23 (patch)
tree27b7c8e3e3888b65dd788e6919a30a5b2deca3d5 /src/network/lookup_name.c
parentb114190b29417fff6f701eea3a3b3b6030338280 (diff)
downloadmusl-2683e267fa6c20d2e7a498a85f79a1dfc4301f23.tar.gz
musl-2683e267fa6c20d2e7a498a85f79a1dfc4301f23.tar.xz
musl-2683e267fa6c20d2e7a498a85f79a1dfc4301f23.zip
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.
Diffstat (limited to 'src/network/lookup_name.c')
-rw-r--r--src/network/lookup_name.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index 0225a934..df9e623e 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -9,6 +9,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <errno.h>
 #include "lookup.h"
 #include "stdio_impl.h"
 #include "syscall.h"
@@ -51,7 +52,14 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
 	int cnt = 0;
 	unsigned char _buf[1032];
 	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
-	if (!f) return 0;
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return 0;
+	default:
+		return EAI_SYSTEM;
+	}
 	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
 		char *p, *z;