NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/48881: /etc/hosts file parsing broken (since Aug 2013)



>Number:         48881
>Category:       lib
>Synopsis:       /etc/hosts file parsing broken (since Aug 2013)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 08 04:15:00 +0000 2014
>Originator:     Greg A. Woods
>Release:        NetBSD current 2014/06/06
>Organization:
Planix, Inc.; Kelowna, BC; Canada
>Environment:
        
        
System: NetBSD
>Description:

        some massive changes to the gethost*() functions introduced a
        bug in the parsing of the /etc/hosts file due to unsafe use of
        fgetln():

        http://mail-index.netbsd.org/source-changes/2013/08/16/msg046780.html

>How-To-Repeat:

        try running a LAN server with /etc/hosts alone

>Fix:

        This is most definitely _NOT_ the best or safest fix, but it
        does work for me for now.

        I don't think fgetln() ensures an extra byte at the end of
        buffer is always available to be clobbered with a NUL.

        A proper fix that also deals with the missing-last-newline issue
        will probably require copying the line (up to the first newline
        or llen, whichever comes first) to a new buffer anyway (as per
        the example in fgetln(3)) so maybe that should be done for every
        line just to be safe.

        The final fix will need to be pulled up to netbsd-5 and netbsd-6 too.

Index: gethnamaddr.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/lib/libc/net/gethnamaddr.c,v
retrieving revision 1.90
diff -u -u -r1.90 gethnamaddr.c
--- gethnamaddr.c       24 Jan 2014 17:26:18 -0000      1.90
+++ gethnamaddr.c       8 Jun 2014 03:56:37 -0000
@@ -740,6 +740,7 @@
 {
        char *p, *name;
        char *cp, **q;
+       char nxt;
        int af, len;
        size_t llen, anum;
        char **aliases;
@@ -762,12 +763,17 @@
                goto again;
        if (*p == '#')
                goto again;
-       p[llen] = '\0';
-       if (!(cp = strpbrk(p, "#\n")))
+       nxt = p[llen];                  /* xxx this may not be safe... */
+       p[llen] = '\0';                 /* xxx this may not be safe... */
+       if (!(cp = strpbrk(p, "#\n"))) {        /* xxx this ignores the last 
line if it does not end in a newline!!! */
+               p[llen] = nxt;
                goto again;
+       }
        *cp = '\0';
-       if (!(cp = strpbrk(p, " \t")))
+       if (!(cp = strpbrk(p, " \t"))) {
+               p[llen] = nxt;
                goto again;
+       }
        *cp++ = '\0';
        if (inet_pton(AF_INET6, p, &host_addr) > 0) {
                af = AF_INET6;
@@ -786,14 +792,18 @@
                }
                __res_put_state(res);
        } else {
+               p[llen] = nxt;
                goto again;
        }
        /* if this is not something we're looking for, skip it. */
-       if (hent->h_addrtype != 0 && hent->h_addrtype != af)
+       if (hent->h_addrtype != 0 && hent->h_addrtype != af) {
+               p[llen] = nxt;
                goto again;
-       if (hent->h_length != 0 && hent->h_length != len)
+       }
+       if (hent->h_length != 0 && hent->h_length != len) {
+               p[llen] = nxt;
                goto again;
-
+       }
        while (*cp == ' ' || *cp == '\t')
                cp++;
        if ((cp = strpbrk(name = cp, " \t")) != NULL)

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index