mirror of
https://github.com/fluencelabs/musl
synced 2025-06-22 03:02:07 +00:00
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.
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "lookup.h"
|
#include "lookup.h"
|
||||||
#include "stdio_impl.h"
|
#include "stdio_impl.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
@ -51,7 +52,14 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
|
|||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
unsigned char _buf[1032];
|
unsigned char _buf[1032];
|
||||||
FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
|
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) {
|
while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
|
||||||
char *p, *z;
|
char *p, *z;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "lookup.h"
|
#include "lookup.h"
|
||||||
#include "stdio_impl.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];
|
unsigned char _buf[1032];
|
||||||
FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
|
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) {
|
while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
|
||||||
if ((p=strchr(line, '#'))) *p++='\n', *p=0;
|
if ((p=strchr(line, '#'))) *p++='\n', *p=0;
|
||||||
|
@ -54,7 +54,15 @@ int __res_msend(int nqueries, const unsigned char *const *queries,
|
|||||||
|
|
||||||
/* Get nameservers from resolv.conf, fallback to localhost */
|
/* Get nameservers from resolv.conf, fallback to localhost */
|
||||||
f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
|
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])) {
|
if (!strncmp(line, "options", 7) && isspace(line[7])) {
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
char *p, *z;
|
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) {
|
if (!nns) {
|
||||||
ns[0].sin.sin_family = AF_INET;
|
ns[0].sin.sin_family = AF_INET;
|
||||||
ns[0].sin.sin_port = htons(53);
|
ns[0].sin.sin_port = htons(53);
|
||||||
|
Reference in New Issue
Block a user