wlantest: Avoid unaligned iphdr pointers
Buffers passed to rx_data_ip() may not be naturally-aligned, and so we get unpredictable behavior when we cast that to an IP header. In particular, this code may crash on ARM. Signed-off-by: Brian Norris <briannorris@chromium.org>
This commit is contained in:
parent
35756c02ea
commit
1e537a2756
1 changed files with 18 additions and 17 deletions
|
@ -120,63 +120,64 @@ void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
|
||||||
const u8 *dst, const u8 *src, const u8 *data, size_t len,
|
const u8 *dst, const u8 *src, const u8 *data, size_t len,
|
||||||
const u8 *peer_addr)
|
const u8 *peer_addr)
|
||||||
{
|
{
|
||||||
const struct ip *ip;
|
struct ip ip;
|
||||||
const u8 *payload;
|
const u8 *payload;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
uint16_t frag_off, ip_len;
|
uint16_t frag_off, ip_len;
|
||||||
|
|
||||||
ip = (const struct ip *) data;
|
if (len < sizeof(ip))
|
||||||
if (len < sizeof(*ip))
|
|
||||||
return;
|
return;
|
||||||
if (ip->ip_v != 4) {
|
os_memcpy(&ip, data, sizeof(ip));
|
||||||
|
|
||||||
|
if (ip.ip_v != 4) {
|
||||||
if (hwsim_test_packet(data, len)) {
|
if (hwsim_test_packet(data, len)) {
|
||||||
add_note(wt, MSG_INFO, "hwsim_test package");
|
add_note(wt, MSG_INFO, "hwsim_test package");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
add_note(wt, MSG_DEBUG, "Unexpected IP protocol version %u in "
|
add_note(wt, MSG_DEBUG, "Unexpected IP protocol version %u in "
|
||||||
"IPv4 packet (bssid=" MACSTR " str=" MACSTR
|
"IPv4 packet (bssid=" MACSTR " str=" MACSTR
|
||||||
" dst=" MACSTR ")", ip->ip_v, MAC2STR(bssid),
|
" dst=" MACSTR ")", ip.ip_v, MAC2STR(bssid),
|
||||||
MAC2STR(src), MAC2STR(dst));
|
MAC2STR(src), MAC2STR(dst));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ip->ip_hl * 4 < sizeof(*ip)) {
|
if (ip.ip_hl * 4 < sizeof(ip)) {
|
||||||
add_note(wt, MSG_DEBUG, "Unexpected IP header length %u in "
|
add_note(wt, MSG_DEBUG, "Unexpected IP header length %u in "
|
||||||
"IPv4 packet (bssid=" MACSTR " str=" MACSTR
|
"IPv4 packet (bssid=" MACSTR " str=" MACSTR
|
||||||
" dst=" MACSTR ")", ip->ip_hl, MAC2STR(bssid),
|
" dst=" MACSTR ")", ip.ip_hl, MAC2STR(bssid),
|
||||||
MAC2STR(src), MAC2STR(dst));
|
MAC2STR(src), MAC2STR(dst));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ip->ip_hl * 4 > len) {
|
if (ip.ip_hl * 4 > len) {
|
||||||
add_note(wt, MSG_DEBUG, "Truncated IP header (ihl=%u len=%u) "
|
add_note(wt, MSG_DEBUG, "Truncated IP header (ihl=%u len=%u) "
|
||||||
"in IPv4 packet (bssid=" MACSTR " str=" MACSTR
|
"in IPv4 packet (bssid=" MACSTR " str=" MACSTR
|
||||||
" dst=" MACSTR ")", ip->ip_hl, (unsigned) len,
|
" dst=" MACSTR ")", ip.ip_hl, (unsigned) len,
|
||||||
MAC2STR(bssid), MAC2STR(src), MAC2STR(dst));
|
MAC2STR(bssid), MAC2STR(src), MAC2STR(dst));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: check header checksum in ip->ip_sum */
|
/* TODO: check header checksum in ip.ip_sum */
|
||||||
|
|
||||||
frag_off = be_to_host16(ip->ip_off);
|
frag_off = be_to_host16(ip.ip_off);
|
||||||
if (frag_off & 0x1fff) {
|
if (frag_off & 0x1fff) {
|
||||||
wpa_printf(MSG_EXCESSIVE, "IP fragment reassembly not yet "
|
wpa_printf(MSG_EXCESSIVE, "IP fragment reassembly not yet "
|
||||||
"supported");
|
"supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_len = be_to_host16(ip->ip_len);
|
ip_len = be_to_host16(ip.ip_len);
|
||||||
if (ip_len > len)
|
if (ip_len > len)
|
||||||
return;
|
return;
|
||||||
if (ip_len < len)
|
if (ip_len < len)
|
||||||
len = ip_len;
|
len = ip_len;
|
||||||
|
|
||||||
payload = data + 4 * ip->ip_hl;
|
payload = data + 4 * ip.ip_hl;
|
||||||
plen = len - 4 * ip->ip_hl;
|
plen = len - 4 * ip.ip_hl;
|
||||||
|
|
||||||
switch (ip->ip_p) {
|
switch (ip.ip_p) {
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
case IPPROTO_ICMP:
|
case IPPROTO_ICMP:
|
||||||
rx_data_icmp(wt, bssid, sta_addr, ip->ip_dst.s_addr,
|
rx_data_icmp(wt, bssid, sta_addr, ip.ip_dst.s_addr,
|
||||||
ip->ip_src.s_addr, payload, plen, peer_addr);
|
ip.ip_src.s_addr, payload, plen, peer_addr);
|
||||||
break;
|
break;
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue