diff options
author | Andreas Schneider <asn@samba.org> | 2014-10-09 09:15:59 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2014-10-09 12:24:03 +0200 |
commit | 895b32b2e39417072bc40afeb21293a08181399f (patch) | |
tree | 810b10296a897df065b41c18cbd4f508902c160c /lib | |
parent | 94c87d134723a432d2d4e908d3c5d44b39fde1ae (diff) | |
download | samba-895b32b2e39417072bc40afeb21293a08181399f.tar.gz samba-895b32b2e39417072bc40afeb21293a08181399f.tar.xz samba-895b32b2e39417072bc40afeb21293a08181399f.zip |
nwrap: Don't overflow the in_addr if convert IPv6.
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/nss_wrapper/nss_wrapper.c | 54 |
1 files changed, 22 insertions, 32 deletions
diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c index 57003bd612..931aaa5989 100644 --- a/lib/nss_wrapper/nss_wrapper.c +++ b/lib/nss_wrapper/nss_wrapper.c @@ -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; |