diff options
author | Andreas Schneider <asn@samba.org> | 2019-02-15 14:19:07 +0100 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2019-02-28 12:48:33 +0100 |
commit | 633e822b128123ac62b2f4322c4215521e45e38a (patch) | |
tree | 6b03e8b2121c9a527e3007808833ae172f18348e | |
parent | d0c03e3806a4b3d84e9cd1b0b7dd05fcfcb48c12 (diff) | |
download | nss_wrapper-633e822b128123ac62b2f4322c4215521e45e38a.tar.gz nss_wrapper-633e822b128123ac62b2f4322c4215521e45e38a.tar.xz nss_wrapper-633e822b128123ac62b2f4322c4215521e45e38a.zip |
nwrap: Fix strict aliasing issue with sockaddr
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
-rw-r--r-- | src/nss_wrapper.c | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/src/nss_wrapper.c b/src/nss_wrapper.c index 0246016..a81145a 100644 --- a/src/nss_wrapper.c +++ b/src/nss_wrapper.c @@ -5204,31 +5204,43 @@ static int nwrap_convert_he_ai(const struct hostent *he, switch (he->h_addrtype) { case AF_INET: { - struct sockaddr_in *sinp = - (struct sockaddr_in *) ai->ai_addr; + union { + struct sockaddr *sa; + struct sockaddr_in *in; + } addr; - memset(sinp, 0, sizeof(struct sockaddr_in)); + addr.sa = ai->ai_addr; - sinp->sin_port = htons(port); - sinp->sin_family = AF_INET; + memset(addr.in, 0, sizeof(struct sockaddr_in)); - memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); - memcpy(&sinp->sin_addr, he->h_addr_list[0], he->h_length); + addr.in->sin_port = htons(port); + addr.in->sin_family = AF_INET; + + memset(addr.in->sin_zero, + '\0', + sizeof (addr.in->sin_zero)); + memcpy(&(addr.in->sin_addr), + he->h_addr_list[0], + he->h_length); } break; #ifdef HAVE_IPV6 case AF_INET6: { - struct sockaddr_in6 *sin6p = - (struct sockaddr_in6 *) ai->ai_addr; + union { + struct sockaddr *sa; + struct sockaddr_in6 *in6; + } addr; + + addr.sa = ai->ai_addr; - memset(sin6p, 0, sizeof(struct sockaddr_in6)); + memset(addr.in6, 0, sizeof(struct sockaddr_in6)); - sin6p->sin6_port = htons(port); - sin6p->sin6_family = AF_INET6; + addr.in6->sin6_port = htons(port); + addr.in6->sin6_family = AF_INET6; - memcpy(&sin6p->sin6_addr, + memcpy(&addr.in6->sin6_addr, he->h_addr_list[0], he->h_length); } @@ -5465,21 +5477,41 @@ static int nwrap_getnameinfo(const struct sockaddr *sa, socklen_t salen, type = sa->sa_family; switch (type) { - case AF_INET: - if (salen < sizeof(struct sockaddr_in)) + case AF_INET: { + union { + const struct sockaddr *sa; + const struct sockaddr_in *in; + } a; + + if (salen < sizeof(struct sockaddr_in)) { return EAI_FAMILY; - addr = &((const struct sockaddr_in *)sa)->sin_addr; - addrlen = sizeof(((const struct sockaddr_in *)sa)->sin_addr); - port = ntohs(((const struct sockaddr_in *)sa)->sin_port); + } + + a.sa = sa; + + addr = &(a.in->sin_addr); + addrlen = sizeof(a.in->sin_addr); + port = ntohs(a.in->sin_port); break; + } #ifdef HAVE_IPV6 - case AF_INET6: - if (salen < sizeof(struct sockaddr_in6)) + case AF_INET6: { + union { + const struct sockaddr *sa; + const struct sockaddr_in6 *in6; + } a; + + if (salen < sizeof(struct sockaddr_in6)) { return EAI_FAMILY; - addr = &((const struct sockaddr_in6 *)sa)->sin6_addr; - addrlen = sizeof(((const struct sockaddr_in6 *)sa)->sin6_addr); - port = ntohs(((const struct sockaddr_in6 *)sa)->sin6_port); + } + + a.sa = sa; + + addr = &(a.in6->sin6_addr); + addrlen = sizeof(a.in6->sin6_addr); + port = ntohs(a.in6->sin6_port); break; + } #endif default: return EAI_FAMILY; |