wlantest: Fix Beacon and Probe Response frame parser

These functions did not verify that the received frame is long enough to
contain the beginning of the variable length IE area. A truncated frame
could have caused a segmentation fault due to reading beyond the buffer.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2015-04-18 17:59:30 +03:00
parent 26b3f64428
commit 762a0bfb01

View file

@ -53,16 +53,19 @@ static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
struct wlantest_bss *bss; struct wlantest_bss *bss;
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
size_t offset;
mgmt = (const struct ieee80211_mgmt *) data; mgmt = (const struct ieee80211_mgmt *) data;
offset = mgmt->u.beacon.variable - data;
if (len < offset)
return;
bss = bss_get(wt, mgmt->bssid); bss = bss_get(wt, mgmt->bssid);
if (bss == NULL) if (bss == NULL)
return; return;
if (bss->proberesp_seen) if (bss->proberesp_seen)
return; /* do not override with Beacon data */ return; /* do not override with Beacon data */
bss->capab_info = le_to_host16(mgmt->u.beacon.capab_info); bss->capab_info = le_to_host16(mgmt->u.beacon.capab_info);
if (ieee802_11_parse_elems(mgmt->u.beacon.variable, if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - offset,
len - (mgmt->u.beacon.variable - data),
&elems, 0) == ParseFailed) { &elems, 0) == ParseFailed) {
if (bss->parse_error_reported) if (bss->parse_error_reported)
return; return;
@ -81,16 +84,19 @@ static void rx_mgmt_probe_resp(struct wlantest *wt, const u8 *data, size_t len)
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
struct wlantest_bss *bss; struct wlantest_bss *bss;
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
size_t offset;
mgmt = (const struct ieee80211_mgmt *) data; mgmt = (const struct ieee80211_mgmt *) data;
offset = mgmt->u.probe_resp.variable - data;
if (len < offset)
return;
bss = bss_get(wt, mgmt->bssid); bss = bss_get(wt, mgmt->bssid);
if (bss == NULL) if (bss == NULL)
return; return;
bss->counters[WLANTEST_BSS_COUNTER_PROBE_RESPONSE]++; bss->counters[WLANTEST_BSS_COUNTER_PROBE_RESPONSE]++;
bss->capab_info = le_to_host16(mgmt->u.probe_resp.capab_info); bss->capab_info = le_to_host16(mgmt->u.probe_resp.capab_info);
if (ieee802_11_parse_elems(mgmt->u.probe_resp.variable, if (ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - offset,
len - (mgmt->u.probe_resp.variable - data),
&elems, 0) == ParseFailed) { &elems, 0) == ParseFailed) {
if (bss->parse_error_reported) if (bss->parse_error_reported)
return; return;