handle non-matching address family entries in hosts file
authorRich Felker <dalias@aerifal.cx>
Wed, 2 Mar 2016 05:34:51 +0000 (00:34 -0500)
committerRich Felker <dalias@aerifal.cx>
Wed, 2 Mar 2016 05:34:51 +0000 (00:34 -0500)
name_from_hosts failed to account for the possibility of an address
family error from name_from_numeric, wrongly counting such a return as
success and using the uninitialized address data as part of the
results passed up to the caller.

non-matching address family entries cannot simply be ignored or
results would be inconsistent with respect to whether AF_UNSPEC or a
specific address family is queried. instead, record that a
non-matching entry was seen, and fail the lookup with EAI_NONAME of no
matching-family entries are found.

src/network/lookup_name.c

index a26ad535143e7651807c5d153fb4c1fab4ea5a73..86f90ac1b74b9b11183d8a495667da2d9989b7f4 100644 (file)
@@ -49,7 +49,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
 {
        char line[512];
        size_t l = strlen(name);
-       int cnt = 0;
+       int cnt = 0, badfam = 0;
        unsigned char _buf[1032];
        FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
        if (!f) switch (errno) {
@@ -71,8 +71,16 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
                /* Isolate IP address to parse */
                for (p=line; *p && !isspace(*p); p++);
                *p++ = 0;
-               if (name_from_numeric(buf+cnt, line, family))
+               switch (name_from_numeric(buf+cnt, line, family)) {
+               case 1:
                        cnt++;
+                       break;
+               case 0:
+                       continue;
+               default:
+                       badfam = EAI_NONAME;
+                       continue;
+               }
 
                /* Extract first name as canonical name */
                for (; *p && isspace(*p); p++);
@@ -81,7 +89,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
                if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
        }
        __fclose_ca(f);
-       return cnt;
+       return cnt ? cnt : badfam;
 }
 
 struct dpc_ctx {