aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2019-02-15 14:19:07 +0100
committerAndreas Schneider <asn@samba.org>2019-02-28 12:48:33 +0100
commit633e822b128123ac62b2f4322c4215521e45e38a (patch)
tree6b03e8b2121c9a527e3007808833ae172f18348e
parentd0c03e3806a4b3d84e9cd1b0b7dd05fcfcb48c12 (diff)
downloadnss_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.c78
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;