diff options
author | Chao Yang <chao.yang@linaro.org> | 2011-10-10 16:01:32 +0100 |
---|---|---|
committer | Chao Yang <chao.yang@linaro.org> | 2011-10-14 12:10:23 +0100 |
commit | 61e587d3802fe674c4a8f7eab59a5c58b1943536 (patch) | |
tree | 4255f3e75c39c43a263059b8b6a1ba0e2b9420a6 | |
parent | ebf5da42ba598621e9dbb878196254e83c91d8fc (diff) | |
download | dnsmasq-linaro_android_2.3.5.tar.gz |
dnsmasq: fix strict aliasing violationslinaro_android_2.3.7linaro_android_2.3.5
This patch fixes strict aliasing violations and removes -fno-strict-aliasing
compiler flag in Android.mk
Change-Id: I8d9ba5ce65459f743959f0a2b44dbea9fe29d02d
-rw-r--r-- | src/Android.mk | 3 | ||||
-rwxr-xr-x | src/dhcp.c | 25 | ||||
-rwxr-xr-x | src/dnsmasq.c | 15 | ||||
-rwxr-xr-x | src/forward.c | 84 | ||||
-rwxr-xr-x | src/log.c | 5 | ||||
-rwxr-xr-x | src/netlink.c | 16 | ||||
-rwxr-xr-x | src/network.c | 21 | ||||
-rwxr-xr-x | src/rfc1035.c | 7 | ||||
-rwxr-xr-x | src/rfc2131.c | 4 |
9 files changed, 132 insertions, 48 deletions
diff --git a/src/Android.mk b/src/Android.mk index 5360eb8..2dead47 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -10,7 +10,8 @@ LOCAL_MODULE := dnsmasq LOCAL_C_INCLUDES := external/dnsmasq/src -LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DNO_IPV6 -DNO_TFTP -DNO_SCRIPT -fno-strict-aliasing +LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DNO_IPV6 -DNO_TFTP -DNO_SCRIPT -Werror=strict-aliasing + LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils include $(BUILD_EXECUTABLE) @@ -72,8 +72,9 @@ void dhcp_init(void) #ifdef HAVE_SOCKADDR_SA_LEN saddr.sin_len = sizeof(struct sockaddr_in); #endif - - if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in))) + union {void* src; struct sockaddr* dst;} u_cast; + u_cast.src = &saddr; + if (bind(fd, u_cast.dst, sizeof(struct sockaddr_in))) die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET); daemon->dhcpfd = fd; @@ -207,8 +208,10 @@ void dhcp_packet(time_t now) ifr.ifr_addr.sa_family = AF_INET; if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 ) { + union {void* src; struct sockaddr_in* dst;}u_cast; addrp = &iface_addr; - iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; + u_cast.src = &ifr.ifr_addr; + iface_addr = (u_cast.dst)->sin_addr; } if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, &iface_index)) @@ -227,7 +230,11 @@ void dhcp_packet(time_t now) return; } else - iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; + { + union {void* src; struct sockaddr_in* dst;}u_cast; + u_cast.src = &ifr.ifr_addr; + iface_addr = (u_cast.dst)->sin_addr; + } } /* unlinked contexts are marked by context->current == context */ @@ -306,9 +313,11 @@ void dhcp_packet(time_t now) /* unicast to unconfigured client. Inject mac address direct into ARP cache. struct sockaddr limits size to 14 bytes. */ struct arpreq req; + union {void* src; struct sockaddr_in* dst;}u_cast; dest.sin_addr = mess->yiaddr; dest.sin_port = htons(daemon->dhcp_client_port); - *((struct sockaddr_in *)&req.arp_pa) = dest; + u_cast.src = &req.arp_pa; + *u_cast.dst = dest; req.arp_ha.sa_family = mess->htype; memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen); strncpy(req.arp_dev, ifr.ifr_name, 16); @@ -964,11 +973,13 @@ char *host_from_dns(struct in_addr addr) struct crec *lookup; char *hostname = NULL; char *d1, *d2; + union {void* src; struct all_addr* dst;}u_cast; if (daemon->port == 0) return NULL; /* DNS disabled. */ - - lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4); + + u_cast.src = &addr; + lookup = cache_find_by_addr(NULL, u_cast.dst, 0, F_IPV4); if (lookup && (lookup->flags & F_HOSTS)) { hostname = daemon->dhcp_buff; diff --git a/src/dnsmasq.c b/src/dnsmasq.c index 1a9d808..5f6a6f7 100755 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -1132,7 +1132,7 @@ static void check_dns_listeners(fd_set *set, time_t now) /* interface may be new since startup */ if (enumerate_interfaces() && - getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) != -1) + getsockname(confd, (struct sockaddr*)&tcp_addr.sa, &tcp_len) != -1) for (iface = daemon->interfaces; iface; iface = iface->next) if (sockaddr_isequal(&iface->addr, &tcp_addr)) break; @@ -1250,6 +1250,8 @@ int icmp_ping(struct in_addr addr) unsigned int i, j; int gotreply = 0; time_t start, now; + union {void* src; struct sockaddr* dst;}u_cast; + union {void* src; u16* dst;}u16_cast; #if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK) if ((fd = make_icmp_sock()) == -1) @@ -1270,14 +1272,16 @@ int icmp_ping(struct in_addr addr) memset(&packet.icmp, 0, sizeof(packet.icmp)); packet.icmp.icmp_type = ICMP_ECHO; packet.icmp.icmp_id = id; + u16_cast.src = &packet.icmp; for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++) - j += ((u16 *)&packet.icmp)[i]; + j += u16_cast.dst[i]; while (j>>16) j = (j & 0xffff) + (j >> 16); packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j; - + + u_cast.src = &saddr; while (sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0, - (struct sockaddr *)&saddr, sizeof(saddr)) == -1 && + u_cast.dst, sizeof(saddr)) == -1 && retry_send()); for (now = start = dnsmasq_time(); @@ -1313,9 +1317,10 @@ int icmp_ping(struct in_addr addr) check_tftp_listeners(&rset, now); #endif + u_cast.src = &faddr; if (FD_ISSET(fd, &rset) && recvfrom(fd, &packet, sizeof(packet), 0, - (struct sockaddr *)&faddr, &len) == sizeof(packet) && + u_cast.dst, &len) == sizeof(packet) && saddr.sin_addr.s_addr == faddr.sin_addr.s_addr && packet.icmp.icmp_type == ICMP_ECHOREPLY && packet.icmp.icmp_seq == 0 && diff --git a/src/forward.c b/src/forward.c index 40cda1c..bb7ea1f 100755 --- a/src/forward.c +++ b/src/forward.c @@ -122,6 +122,8 @@ static unsigned short search_servers(time_t now, struct all_addr **addrpp, unsigned int matchlen = 0; struct server *serv; unsigned short flags = 0; + union {struct all_addr* alladdr_p; + void* src; }u_cast; for (serv = daemon->servers; serv; serv=serv->next) /* domain matches take priority over NODOTS matches */ @@ -136,11 +138,17 @@ static unsigned short search_servers(time_t now, struct all_addr **addrpp, if (sflag & qtype) { flags = sflag; - if (serv->addr.sa.sa_family == AF_INET) - *addrpp = (struct all_addr *)&serv->addr.in.sin_addr; + if (serv->addr.sa.sa_family == AF_INET) + { + u_cast.src = &serv->addr.in.sin_addr; + *addrpp = u_cast.alladdr_p; + } #ifdef HAVE_IPV6 else - *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr; + { + u_cast.src = &serv->addr.in6.sin6_addr; + *addrpp = u_cast.alladdr_p; + } #endif } else if (!flags || (flags & F_NXDOMAIN)) @@ -167,11 +175,17 @@ static unsigned short search_servers(time_t now, struct all_addr **addrpp, if (sflag & qtype) { flags = sflag; - if (serv->addr.sa.sa_family == AF_INET) - *addrpp = (struct all_addr *)&serv->addr.in.sin_addr; + if (serv->addr.sa.sa_family == AF_INET) + { + u_cast.src = &serv->addr.in.sin_addr; + *addrpp = u_cast.alladdr_p; + } #ifdef HAVE_IPV6 else - *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr; + { + u_cast.src = &serv->addr.in6.sin6_addr; + *addrpp = u_cast.alladdr_p; + } #endif } else if (!flags || (flags & F_NXDOMAIN)) @@ -212,6 +226,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, unsigned short flags = 0; unsigned short gotname = extract_request(header, plen, daemon->namebuff, NULL); struct server *start = NULL; + union {struct all_addr* alladdr_p; + void* src; }u_cast; /* may be no servers available. */ if (!daemon->servers) @@ -336,12 +352,18 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, if (!gotname) strcpy(daemon->namebuff, "query"); if (start->addr.sa.sa_family == AF_INET) + { + u_cast.src = &start->addr.in.sin_addr; log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&start->addr.in.sin_addr, NULL); + u_cast.alladdr_p, NULL); + } #ifdef HAVE_IPV6 else + { + u_cast.src = &start->addr.in6.sin6_addr; log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&start->addr.in6.sin6_addr, NULL); + u_cast.alladdr_p, NULL); + } #endif start->queries++; forwarded = 1; @@ -588,6 +610,9 @@ void receive_query(struct listener *listen, time_t now) #endif } control_u; + union {struct all_addr* alladdr_p; + struct sockaddr_in* saddr_in_p; + void* src; }u_cast; /* packet buffer overwritten */ daemon->srv_save = NULL; @@ -680,7 +705,8 @@ void receive_query(struct listener *listen, time_t now) ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1) return; - netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; + u_cast.src = &ifr.ifr_addr; + netmask = u_cast.saddr_in_p->sin_addr; } if (extract_request(header, (size_t)n, daemon->namebuff, &type)) @@ -689,13 +715,19 @@ void receive_query(struct listener *listen, time_t now) querystr(types, type); - if (listen->family == AF_INET) + if (listen->family == AF_INET) + { + u_cast.src = &source_addr.in.sin_addr; log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&source_addr.in.sin_addr, types); + u_cast.alladdr_p, types); + } #ifdef HAVE_IPV6 else + { + u_cast.src = &source_addr.in6.sin6_addr; log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&source_addr.in6.sin6_addr, types); + u_cast.alladdr_p, types); + } #endif } @@ -729,6 +761,9 @@ unsigned char *tcp_request(int confd, time_t now, unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ); HEADER *header; struct server *last_server; + union {struct all_addr* alladdr_p; + struct sockaddr* sockaddr_p; + void* src; }u_cast; while (1) { @@ -748,19 +783,26 @@ unsigned char *tcp_request(int confd, time_t now, union mysockaddr peer_addr; socklen_t peer_len = sizeof(union mysockaddr); - if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1) + u_cast.src = &peer_addr; + if (getpeername(confd, u_cast.sockaddr_p, &peer_len) != -1) { char types[20]; querystr(types, qtype); - if (peer_addr.sa.sa_family == AF_INET) + if (peer_addr.sa.sa_family == AF_INET) + { + u_cast.src = &peer_addr.in.sin_addr; log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&peer_addr.in.sin_addr, types); + u_cast.alladdr_p, types); + } #ifdef HAVE_IPV6 else + { + u_cast.src = &peer_addr.in6.sin6_addr; log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&peer_addr.in6.sin6_addr, types); + u_cast.alladdr_p, types); + } #endif } } @@ -846,12 +888,18 @@ unsigned char *tcp_request(int confd, time_t now, if (!gotname) strcpy(daemon->namebuff, "query"); if (last_server->addr.sa.sa_family == AF_INET) + { + u_cast.src = &last_server->addr.in.sin_addr; log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&last_server->addr.in.sin_addr, NULL); + u_cast.alladdr_p, NULL); + } #ifdef HAVE_IPV6 else + { + u_cast.src = &last_server->addr.in6.sin6_addr; log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, - (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL); + u_cast.alladdr_p, NULL); + } #endif /* There's no point in updating the cache, since this process will exit and @@ -210,6 +210,8 @@ static void log_write(void) (ECONNRESET, EDESTADDRREQ are *BSD equivalents) */ struct sockaddr_un logaddr; + union {void* src; + struct sockaddr* sockaddr_p;}u_cast; #ifdef HAVE_SOCKADDR_SA_LEN logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1; @@ -218,7 +220,8 @@ static void log_write(void) strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path)); /* Got connection back? try again. */ - if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1) + u_cast.src = &logaddr; + if (connect(log_fd, u_cast.sockaddr_p, sizeof(logaddr)) != -1) continue; /* errors from connect which mean we should keep trying */ diff --git a/src/netlink.c b/src/netlink.c index 77c4385..b792a07 100755 --- a/src/netlink.c +++ b/src/netlink.c @@ -40,6 +40,8 @@ void netlink_init(void) { struct sockaddr_nl addr; socklen_t slen = sizeof(addr); + union {void* src; + struct sockaddr* sockaddr_p;}u_cast; addr.nl_family = AF_NETLINK; addr.nl_pad = 0; @@ -53,16 +55,18 @@ void netlink_init(void) /* May not be able to have permission to set multicast groups don't die in that case */ if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1) { - if (bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) + u_cast.src = &addr; + if (bind(daemon->netlinkfd, u_cast.sockaddr_p, sizeof(addr)) == -1) { addr.nl_groups = 0; - if (errno != EPERM || bind(daemon->netlinkfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (errno != EPERM || bind(daemon->netlinkfd, u_cast.sockaddr_p, sizeof(addr)) == -1) daemon->netlinkfd = -1; } } + u_cast.src = &addr; if (daemon->netlinkfd == -1 || - getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == 1) + getsockname(daemon->netlinkfd, u_cast.sockaddr_p, &slen) == 1) die(_("cannot create netlink socket: %s"), NULL, EC_MISC); /* save pid assigned by bind() and retrieved by getsockname() */ @@ -135,6 +139,9 @@ int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)()) struct rtgenmsg g; } req; + union {void* src; + struct sockaddr* sockaddr_p;}u_cast; + addr.nl_family = AF_NETLINK; addr.nl_pad = 0; addr.nl_groups = 0; @@ -149,8 +156,9 @@ int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)()) req.g.rtgen_family = family; /* Don't block in recvfrom if send fails */ + u_cast.src = &addr; while((len = sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0, - (struct sockaddr *)&addr, sizeof(addr))) == -1 && retry_send()); + u_cast.sockaddr_p, sizeof(addr))) == -1 && retry_send()); if (len == -1) return 0; diff --git a/src/network.c b/src/network.c index b0ffc6b..e579b00 100755 --- a/src/network.c +++ b/src/network.c @@ -123,6 +123,7 @@ static int iface_allowed(struct irec **irecp, int if_index, struct ifreq ifr; int dhcp_ok = 1; struct iname *tmp; + union {struct all_addr* alladdr_p; void* src;}u_cast; /* check whether the interface IP has been added already we call this routine multiple times. */ @@ -173,8 +174,9 @@ static int iface_allowed(struct irec **irecp, int if_index, } } + u_cast.src = &addr->in.sin_addr; if (addr->sa.sa_family == AF_INET && - !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name, NULL)) + !iface_check(AF_INET, u_cast.alladdr_p, ifr.ifr_name, NULL)) return 1; for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) @@ -339,7 +341,7 @@ struct listener *create_wildcard_listeners(void) return NULL; if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || - bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 || + bind(tcpfd, (struct sockaddr *)&addr.sa, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 || !fix_fd(tcpfd) || #ifdef HAVE_IPV6 @@ -353,7 +355,7 @@ struct listener *create_wildcard_listeners(void) setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 || setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 || #endif - bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1) + bind(fd, (struct sockaddr *)&addr.sa, sa_len(&addr)) == -1) return NULL; } @@ -518,8 +520,7 @@ int random_sock(int family) #endif } #endif - - if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0) + if (bind(fd, (struct sockaddr *)&addr.sa, sa_len(&addr)) == 0) return fd; if (errno != EADDRINUSE && errno != EACCES) @@ -548,7 +549,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp) #endif } - if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1) + if (bind(fd, (struct sockaddr *)&addr_copy.sa, sa_len(&addr_copy)) == -1) return 0; #if defined(SO_BINDTODEVICE) @@ -959,16 +960,18 @@ struct in_addr get_ifaddr(char *intr) { struct listener *l; struct ifreq ifr; + union{struct sockaddr_in* in_p; void* src;}u_cast; for (l = daemon->listeners; l && l->family != AF_INET; l = l->next); strncpy(ifr.ifr_name, intr, IF_NAMESIZE); ifr.ifr_addr.sa_family = AF_INET; + u_cast.src = &ifr.ifr_addr; if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1) - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1; - - return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; + u_cast.in_p->sin_addr.s_addr = -1; + + return (u_cast.in_p)->sin_addr; } diff --git a/src/rfc1035.c b/src/rfc1035.c index ca5ceba..7b16da3 100755 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -1140,6 +1140,7 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct crec *crecp; int nxdomain = 0, auth = 1, trunc = 0; struct mx_srv_record *rec; + union {struct in_addr* in_p; void* src;}u_cast; /* If there is an RFC2671 pseudoheader then it will be overwritten by partial replies, so we have to do a dry run to see if we can answer @@ -1380,8 +1381,9 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, { struct crec *save = crecp; do { + u_cast.src = &crecp->addr; if ((crecp->flags & F_HOSTS) && - is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask)) + is_same_net(*u_cast.in_p, local_addr, local_netmask)) { localise = 1; break; @@ -1425,9 +1427,10 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, { /* If we are returning local answers depending on network, filter here. */ + u_cast.src = &crecp->addr; if (localise && (crecp->flags & F_HOSTS) && - !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask)) + !is_same_net(*u_cast.in_p, local_addr, local_netmask)) continue; if (!(crecp->flags & (F_HOSTS | F_DHCP))) diff --git a/src/rfc2131.c b/src/rfc2131.c index 1ef8569..6d1995e 100755 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -164,10 +164,12 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, /* check for DHCP rather than BOOTP */ if ((opt = option_find(mess, sz, OPTION_MESSAGE_TYPE, 1))) { + u32 data32; mess_type = option_uint(opt, 0, 1); /* only insist on a cookie for DHCP. */ - if (*((u32 *)&mess->options) != htonl(DHCP_COOKIE)) + memcpy(&data32, &mess->options, sizeof(data32)); + if (data32 != htonl(DHCP_COOKIE)) return 0; /* two things to note here: expand_buf may move the packet, |