OSDN Git Service

resolv: various memory corruption and off by one fixes
authorTimo Teras <timo.teras@iki.fi>
Fri, 7 May 2010 14:19:20 +0000 (17:19 +0300)
committerAustin Foxley <austinf@cetoncorp.com>
Fri, 7 May 2010 15:34:21 +0000 (08:34 -0700)
Fixes resolution of names with AAAA entries and gethostbyaddr issues.

Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
libc/inet/resolv.c

index 84289a6..320aec4 100644 (file)
@@ -689,7 +689,7 @@ int attribute_hidden __decode_dotted(const unsigned char *packet,
 
                if (used + b + 1 >= dest_len)
                        return -1;
-               if (offset + b + 1 >= packet_len)
+               if (offset + b >= packet_len)
                        return -1;
                memcpy(dest + used, packet + offset, b);
                offset += b;
@@ -2417,7 +2417,7 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
        /* Layout in buf:
         * char *alias[ALIAS_DIM];
         * struct in[6]_addr* addr_list[2];
-        * struct in[6]_addr* in;
+        * struct in[6]_addr in;
         * char scratch_buffer[256+];
         */
 #define in6 ((struct in6_addr *)in)
@@ -2431,9 +2431,13 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
 #ifndef __UCLIBC_HAS_IPV6__
        buf += sizeof(*in);
        buflen -= sizeof(*in);
+       if (addrlen > sizeof(*in))
+               return ERANGE;
 #else
        buf += sizeof(*in6);
        buflen -= sizeof(*in6);
+       if (addrlen > sizeof(*in6))
+               return ERANGE;
 #endif
        if ((ssize_t)buflen < 256)
                return ERANGE;
@@ -2441,7 +2445,7 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
        alias[1] = NULL;
        addr_list[0] = in;
        addr_list[1] = NULL;
-       memcpy(&in, addr, addrlen);
+       memcpy(in, addr, addrlen);
 
        if (0) /* nothing */;
 #ifdef __UCLIBC_HAS_IPV4__
@@ -2456,7 +2460,7 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
                char *dst = buf;
                unsigned char *tp = (unsigned char *)addr + addrlen - 1;
                do {
-                       dst += sprintf(dst, "%x.%x.", tp[i] & 0xf, tp[i] >> 4);
+                       dst += sprintf(dst, "%x.%x.", tp[0] & 0xf, tp[0] >> 4);
                        tp--;
                } while (tp >= (unsigned char *)addr);
                strcpy(dst, "ip6.arpa");