WNM: Avoid undefined behavior in pointer arithmetic
Reorder terms in a way that no invalid pointers are generated with pos+len operations. end-pos is always defined (with a valid pos pointer) while pos+len could end up pointing beyond the end pointer which would be undefined behavior. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
1f32a23962
commit
bdce45b83e
1 changed files with 12 additions and 12 deletions
|
@ -187,8 +187,8 @@ static void wnm_sleep_mode_exit_success(struct wpa_supplicant *wpa_s,
|
||||||
end = ptr + key_len_total;
|
end = ptr + key_len_total;
|
||||||
wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total);
|
wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total);
|
||||||
|
|
||||||
while (ptr + 1 < end) {
|
while (end - ptr > 1) {
|
||||||
if (ptr + 2 + ptr[1] > end) {
|
if (2 + ptr[1] > end - ptr) {
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Invalid Key Data element "
|
wpa_printf(MSG_DEBUG, "WNM: Invalid Key Data element "
|
||||||
"length");
|
"length");
|
||||||
if (end > ptr) {
|
if (end > ptr) {
|
||||||
|
@ -259,9 +259,9 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos += 3 + key_len_total;
|
pos += 3 + key_len_total;
|
||||||
while (pos - frm < len) {
|
while (pos - frm + 1 < len) {
|
||||||
u8 ie_len = *(pos + 1);
|
u8 ie_len = *(pos + 1);
|
||||||
if (pos + 2 + ie_len > frm + len) {
|
if (2 + ie_len > frm + len - pos) {
|
||||||
wpa_printf(MSG_INFO, "WNM: Invalid IE len %u", ie_len);
|
wpa_printf(MSG_INFO, "WNM: Invalid IE len %u", ie_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -790,7 +790,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
|
||||||
unsigned int beacon_int;
|
unsigned int beacon_int;
|
||||||
u8 valid_int;
|
u8 valid_int;
|
||||||
|
|
||||||
if (pos + 5 > end)
|
if (end - pos < 5)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wpa_s->current_bss)
|
if (wpa_s->current_bss)
|
||||||
|
@ -813,7 +813,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
|
||||||
pos += 5;
|
pos += 5;
|
||||||
|
|
||||||
if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
|
if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
|
||||||
if (pos + 12 > end) {
|
if (end - pos < 12) {
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Too short BSS TM Request");
|
wpa_printf(MSG_DEBUG, "WNM: Too short BSS TM Request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -824,7 +824,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
|
if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
|
||||||
char url[256];
|
char url[256];
|
||||||
|
|
||||||
if (pos + 1 > end || pos + 1 + pos[0] > end) {
|
if (end - pos < 1 || 1 + pos[0] > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Invalid BSS Transition "
|
wpa_printf(MSG_DEBUG, "WNM: Invalid BSS Transition "
|
||||||
"Management Request (URL)");
|
"Management Request (URL)");
|
||||||
return;
|
return;
|
||||||
|
@ -860,7 +860,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->wnm_neighbor_report_elements == NULL)
|
if (wpa_s->wnm_neighbor_report_elements == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (pos + 2 <= end &&
|
while (end - pos >= 2 &&
|
||||||
wpa_s->wnm_num_neighbor_report < WNM_MAX_NEIGHBOR_REPORT)
|
wpa_s->wnm_num_neighbor_report < WNM_MAX_NEIGHBOR_REPORT)
|
||||||
{
|
{
|
||||||
u8 tag = *pos++;
|
u8 tag = *pos++;
|
||||||
|
@ -868,7 +868,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Neighbor report tag %u",
|
wpa_printf(MSG_DEBUG, "WNM: Neighbor report tag %u",
|
||||||
tag);
|
tag);
|
||||||
if (pos + len > end) {
|
if (len > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Truncated request");
|
wpa_printf(MSG_DEBUG, "WNM: Truncated request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -971,7 +971,7 @@ static void ieee802_11_rx_wnm_notif_req_wfa(struct wpa_supplicant *wpa_s,
|
||||||
pos = data;
|
pos = data;
|
||||||
end = data + len;
|
end = data + len;
|
||||||
|
|
||||||
while (pos + 1 < end) {
|
while (end - pos > 1) {
|
||||||
ie = *pos++;
|
ie = *pos++;
|
||||||
ie_len = *pos++;
|
ie_len = *pos++;
|
||||||
wpa_printf(MSG_DEBUG, "WNM: WFA subelement %u len %u",
|
wpa_printf(MSG_DEBUG, "WNM: WFA subelement %u len %u",
|
||||||
|
@ -1009,7 +1009,7 @@ static void ieee802_11_rx_wnm_notif_req_wfa(struct wpa_supplicant *wpa_s,
|
||||||
url = NULL;
|
url = NULL;
|
||||||
osu_method = 1;
|
osu_method = 1;
|
||||||
} else {
|
} else {
|
||||||
if (pos + url_len + 1 > ie_end) {
|
if (url_len + 1 > ie_end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Not enough room for Server URL (len=%u) and Server Method (left %d)",
|
wpa_printf(MSG_DEBUG, "WNM: Not enough room for Server URL (len=%u) and Server Method (left %d)",
|
||||||
url_len,
|
url_len,
|
||||||
(int) (ie_end - pos));
|
(int) (ie_end - pos));
|
||||||
|
@ -1048,7 +1048,7 @@ static void ieee802_11_rx_wnm_notif_req_wfa(struct wpa_supplicant *wpa_s,
|
||||||
"Imminent - Reason Code %u "
|
"Imminent - Reason Code %u "
|
||||||
"Re-Auth Delay %u URL Length %u",
|
"Re-Auth Delay %u URL Length %u",
|
||||||
code, reauth_delay, url_len);
|
code, reauth_delay, url_len);
|
||||||
if (pos + url_len > ie_end)
|
if (url_len > ie_end - pos)
|
||||||
break;
|
break;
|
||||||
url = os_malloc(url_len + 1);
|
url = os_malloc(url_len + 1);
|
||||||
if (url == NULL)
|
if (url == NULL)
|
||||||
|
|
Loading…
Reference in a new issue