nwrap: Don't overflow the in_addr if convert IPv6.
authorAndreas Schneider <asn@samba.org>
Tue, 9 Sep 2014 09:03:24 +0000 (11:03 +0200)
committerAndreas Schneider <asn@samba.org>
Tue, 9 Sep 2014 12:06:36 +0000 (14:06 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
src/nss_wrapper.c

index 57003bd612f56a95157b0b2c4f5456c0005472a4..931aaa5989bd8694c91ee3bf612377cb2f65b01d 100644 (file)
@@ -3854,13 +3854,18 @@ static int nwrap_getaddrinfo(const char *node,
        struct addrinfo *p = NULL;
        unsigned short port = 0;
        struct hostent *he;
-       struct in_addr in;
-       bool is_addr_ipv4 = false;
-       bool is_addr_ipv6 = false;
+       struct {
+               int family;
+               union {
+                       struct in_addr v4;
+#ifdef HAVE_IPV6
+                       struct in6_addr v6;
+               } in;
+#endif
+       } addr;
        int eai = EAI_SYSTEM;
        int ret;
        int rc;
-       int af;
 
        if (node == NULL && service == NULL) {
                return EAI_NONAME;
@@ -3912,32 +3917,25 @@ static int nwrap_getaddrinfo(const char *node,
                }
        }
 
-       af = hints->ai_family;
-       if (af == AF_UNSPEC) {
-               af = AF_INET;
+       rc = 0;
+       if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET) {
+               rc = inet_pton(AF_INET, node, &addr.in.v4);
        }
-
-       rc = inet_pton(af, node, &in);
        if (rc == 1) {
-               is_addr_ipv4 = true;
-               if (af == AF_UNSPEC) {
-                       af = AF_INET;
-               }
+               addr.family = AF_INET;
 #ifdef HAVE_IPV6
        } else {
-               struct in6_addr in6;
-
-               af = AF_INET6;
-
-               rc = inet_pton(af, node, &in6);
+               rc = inet_pton(AF_INET6, node, &addr.in.v6);
                if (rc == 1) {
-                       is_addr_ipv6 = true;
+                       addr.family = AF_INET6;
                }
 #endif
        }
 
-       if (is_addr_ipv4) {
-               he = nwrap_files_gethostbyaddr(&in, sizeof(struct in_addr), af);
+       if (addr.family == AF_INET) {
+               he = nwrap_files_gethostbyaddr(&addr.in.v4,
+                                              sizeof(struct in_addr),
+                                              addr.family);
                if (he != NULL) {
                        rc = nwrap_convert_he_ai(he, port, hints, &ai);
                } else {
@@ -3945,18 +3943,10 @@ static int nwrap_getaddrinfo(const char *node,
                        rc = -1;
                }
 #ifdef HAVE_IPV6
-       } else if (is_addr_ipv6) {
-               struct in6_addr in6;
-
-               rc =  inet_pton(af, node, &in6);
-               if (rc <= 0) {
-                       eai = EAI_ADDRFAMILY;
-                       return ret == 0 ? 0 : eai;
-               }
-
-               he = nwrap_files_gethostbyaddr(&in6,
+       } else if (addr.family == AF_INET6) {
+               he = nwrap_files_gethostbyaddr(&addr.in.v6,
                                               sizeof(struct in6_addr),
-                                              af);
+                                              addr.family);
                if (he != NULL) {
                        rc = nwrap_convert_he_ai(he, port, hints, &ai);
                        eai = rc;