mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-18 10:54:03 -05:00
ndisc_snoop: Avoid misaligned read of IPv6 address
The IPv6 address in the frame buffer may not be 32-bit aligned, so use a local copy to align this before reading the address with 32-bit reads (s6_addr32[]). Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
e9ed7d9898
commit
cf6fd19b34
@ -98,7 +98,7 @@ static void handle_ndisc(void *ctx, const u8 *src_addr, const u8 *buf,
|
|||||||
{
|
{
|
||||||
struct hostapd_data *hapd = ctx;
|
struct hostapd_data *hapd = ctx;
|
||||||
struct icmpv6_ndmsg *msg;
|
struct icmpv6_ndmsg *msg;
|
||||||
struct in6_addr *saddr;
|
struct in6_addr saddr;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
int res;
|
int res;
|
||||||
char addrtxt[INET6_ADDRSTRLEN + 1];
|
char addrtxt[INET6_ADDRSTRLEN + 1];
|
||||||
@ -113,25 +113,30 @@ static void handle_ndisc(void *ctx, const u8 *src_addr, const u8 *buf,
|
|||||||
if (msg->opt_type != SOURCE_LL_ADDR)
|
if (msg->opt_type != SOURCE_LL_ADDR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
saddr = &msg->ipv6h.ip6_src;
|
/*
|
||||||
if (!(saddr->s6_addr32[0] == 0 && saddr->s6_addr32[1] == 0 &&
|
* IPv6 header may not be 32-bit aligned in the buffer, so use
|
||||||
saddr->s6_addr32[2] == 0 && saddr->s6_addr32[3] == 0)) {
|
* a local copy to avoid unaligned reads.
|
||||||
|
*/
|
||||||
|
os_memcpy(&saddr, &msg->ipv6h.ip6_src, sizeof(saddr));
|
||||||
|
if (!(saddr.s6_addr32[0] == 0 && saddr.s6_addr32[1] == 0 &&
|
||||||
|
saddr.s6_addr32[2] == 0 && saddr.s6_addr32[3] == 0)) {
|
||||||
if (len < ETH_HLEN + sizeof(*msg) + ETH_ALEN)
|
if (len < ETH_HLEN + sizeof(*msg) + ETH_ALEN)
|
||||||
return;
|
return;
|
||||||
sta = ap_get_sta(hapd, msg->opt_lladdr);
|
sta = ap_get_sta(hapd, msg->opt_lladdr);
|
||||||
if (!sta)
|
if (!sta)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sta_has_ip6addr(sta, saddr))
|
if (sta_has_ip6addr(sta, &saddr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (inet_ntop(AF_INET6, saddr, addrtxt, sizeof(addrtxt))
|
if (inet_ntop(AF_INET6, &saddr, addrtxt,
|
||||||
== NULL)
|
sizeof(addrtxt)) == NULL)
|
||||||
addrtxt[0] = '\0';
|
addrtxt[0] = '\0';
|
||||||
wpa_printf(MSG_DEBUG, "ndisc_snoop: Learned new IPv6 address %s for "
|
wpa_printf(MSG_DEBUG, "ndisc_snoop: Learned new IPv6 address %s for "
|
||||||
MACSTR, addrtxt, MAC2STR(sta->addr));
|
MACSTR, addrtxt, MAC2STR(sta->addr));
|
||||||
hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) saddr);
|
hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &saddr);
|
||||||
res = hostapd_drv_br_add_ip_neigh(hapd, 6, (u8 *) saddr,
|
res = hostapd_drv_br_add_ip_neigh(hapd, 6,
|
||||||
|
(u8 *) &saddr,
|
||||||
128, sta->addr);
|
128, sta->addr);
|
||||||
if (res) {
|
if (res) {
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
@ -140,7 +145,7 @@ static void handle_ndisc(void *ctx, const u8 *src_addr, const u8 *buf,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sta_ip6addr_add(sta, saddr))
|
if (sta_ip6addr_add(sta, &saddr))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user