diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index b3861f5be..626d74fb7 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -356,8 +356,9 @@ static int wpa_driver_nl80211_send_oper_ifla( req.ifinfo.ifi_change = 0; if (linkmode != -1) { - rta = (struct rtattr *) - ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)); + rta = aliasing_hide_typecast( + ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), + struct rtattr); rta->rta_type = IFLA_LINKMODE; rta->rta_len = RTA_LENGTH(sizeof(char)); *((char *) RTA_DATA(rta)) = linkmode; diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index ade8904ce..a291813bb 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -65,8 +65,9 @@ static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv, req.ifinfo.ifi_change = 0; if (linkmode != -1) { - rta = (struct rtattr *) - ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)); + rta = aliasing_hide_typecast( + ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), + struct rtattr); rta->rta_type = IFLA_LINKMODE; rta->rta_len = RTA_LENGTH(sizeof(char)); *((char *) RTA_DATA(rta)) = linkmode; diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c index fb357705e..48d1bde02 100644 --- a/src/l2_packet/l2_packet_linux.c +++ b/src/l2_packet/l2_packet_linux.c @@ -185,7 +185,7 @@ int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) return -1; } close(s); - saddr = (struct sockaddr_in *) &ifr.ifr_addr; + saddr = aliasing_hide_typecast(&ifr.ifr_addr, struct sockaddr_in); if (saddr->sin_family != AF_INET) return -1; res = os_strlcpy(buf, inet_ntoa(saddr->sin_addr), len); diff --git a/src/utils/common.c b/src/utils/common.c index cb373c3de..9a46ebe46 100644 --- a/src/utils/common.c +++ b/src/utils/common.c @@ -325,3 +325,9 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) } return ssid_txt; } + + +void * __hide_aliasing_typecast(void *foo) +{ + return foo; +} diff --git a/src/utils/common.h b/src/utils/common.h index e6a0f899d..d649391e3 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -442,4 +442,17 @@ static inline int is_zero_ether_addr(const u8 *a) #include "wpa_debug.h" + +/* + * gcc 4.4 ends up generating strict-aliasing warnings about some very common + * networking socket uses that do not really result in a real problem and + * cannot be easily avoided with union-based type-punning due to struct + * definitions including another struct in system header files. To avoid having + * to fully disable strict-aliasing warnings, provide a mechanism to hide the + * typecast from aliasing for now. A cleaner solution will hopefully be found + * in the future to handle these cases. + */ +void * __hide_aliasing_typecast(void *foo); +#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a)) + #endif /* COMMON_H */ diff --git a/src/wps/wps_upnp_ssdp.c b/src/wps/wps_upnp_ssdp.c index 47be4769c..92b785c44 100644 --- a/src/wps/wps_upnp_ssdp.c +++ b/src/wps/wps_upnp_ssdp.c @@ -799,11 +799,11 @@ int add_ssdp_network(char *net_if) goto fail; rt.rt_dev = net_if; - sin = (struct sockaddr_in *) &rt.rt_dst; + sin = aliasing_hide_typecast(&rt.rt_dst, struct sockaddr_in); sin->sin_family = AF_INET; sin->sin_port = 0; sin->sin_addr.s_addr = inet_addr(SSDP_TARGET); - sin = (struct sockaddr_in *) &rt.rt_genmask; + sin = aliasing_hide_typecast(&rt.rt_genmask, struct sockaddr_in); sin->sin_family = AF_INET; sin->sin_port = 0; sin->sin_addr.s_addr = inet_addr(SSDP_NETMASK);