GAS server: 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
1e72ba2e61
commit
f88bcad015
1 changed files with 12 additions and 12 deletions
|
@ -401,7 +401,7 @@ static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd,
|
||||||
|
|
||||||
pos = home_realm;
|
pos = home_realm;
|
||||||
end = pos + home_realm_len;
|
end = pos + home_realm_len;
|
||||||
if (pos + 1 > end) {
|
if (end - pos < 1) {
|
||||||
wpa_hexdump(MSG_DEBUG, "Too short NAI Home Realm Query",
|
wpa_hexdump(MSG_DEBUG, "Too short NAI Home Realm Query",
|
||||||
home_realm, home_realm_len);
|
home_realm, home_realm_len);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -409,7 +409,7 @@ static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd,
|
||||||
num_realms = *pos++;
|
num_realms = *pos++;
|
||||||
|
|
||||||
for (i = 0; i < num_realms && num_matching < 10; i++) {
|
for (i = 0; i < num_realms && num_matching < 10; i++) {
|
||||||
if (pos + 2 > end) {
|
if (end - pos < 2) {
|
||||||
wpa_hexdump(MSG_DEBUG,
|
wpa_hexdump(MSG_DEBUG,
|
||||||
"Truncated NAI Home Realm Query",
|
"Truncated NAI Home Realm Query",
|
||||||
home_realm, home_realm_len);
|
home_realm, home_realm_len);
|
||||||
|
@ -417,7 +417,7 @@ static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
encoding = *pos++;
|
encoding = *pos++;
|
||||||
realm_len = *pos++;
|
realm_len = *pos++;
|
||||||
if (pos + realm_len > end) {
|
if (realm_len > end - pos) {
|
||||||
wpa_hexdump(MSG_DEBUG,
|
wpa_hexdump(MSG_DEBUG,
|
||||||
"Truncated NAI Home Realm Query",
|
"Truncated NAI Home Realm Query",
|
||||||
home_realm, home_realm_len);
|
home_realm, home_realm_len);
|
||||||
|
@ -991,7 +991,7 @@ static void rx_anqp_query_list(struct hostapd_data *hapd,
|
||||||
wpa_printf(MSG_DEBUG, "ANQP: %u Info IDs requested in Query list",
|
wpa_printf(MSG_DEBUG, "ANQP: %u Info IDs requested in Query list",
|
||||||
(unsigned int) (end - pos) / 2);
|
(unsigned int) (end - pos) / 2);
|
||||||
|
|
||||||
while (pos + 2 <= end) {
|
while (end - pos >= 2) {
|
||||||
rx_anqp_query_list_id(hapd, WPA_GET_LE16(pos), qi);
|
rx_anqp_query_list_id(hapd, WPA_GET_LE16(pos), qi);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1080,7 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
|
||||||
u32 oui;
|
u32 oui;
|
||||||
u8 subtype;
|
u8 subtype;
|
||||||
|
|
||||||
if (pos + 4 > end) {
|
if (end - pos < 4) {
|
||||||
wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
|
wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
|
||||||
"Query element");
|
"Query element");
|
||||||
return;
|
return;
|
||||||
|
@ -1116,7 +1116,7 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
if (pos + 1 >= end)
|
if (end - pos <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
subtype = *pos++;
|
subtype = *pos++;
|
||||||
|
@ -1244,12 +1244,12 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
|
||||||
adv_proto = pos++;
|
adv_proto = pos++;
|
||||||
|
|
||||||
slen = *pos++;
|
slen = *pos++;
|
||||||
next = pos + slen;
|
if (slen > end - pos || slen < 2) {
|
||||||
if (next > end || slen < 2) {
|
|
||||||
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
|
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
|
||||||
"GAS: Invalid IE in GAS Initial Request");
|
"GAS: Invalid IE in GAS Initial Request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
next = pos + slen;
|
||||||
pos++; /* skip QueryRespLenLimit and PAME-BI */
|
pos++; /* skip QueryRespLenLimit and PAME-BI */
|
||||||
|
|
||||||
if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
|
if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
|
||||||
|
@ -1276,11 +1276,11 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
|
||||||
|
|
||||||
pos = next;
|
pos = next;
|
||||||
/* Query Request */
|
/* Query Request */
|
||||||
if (pos + 2 > end)
|
if (end - pos < 2)
|
||||||
return;
|
return;
|
||||||
slen = WPA_GET_LE16(pos);
|
slen = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
if (pos + slen > end)
|
if (slen > end - pos)
|
||||||
return;
|
return;
|
||||||
end = pos + slen;
|
end = pos + slen;
|
||||||
|
|
||||||
|
@ -1288,7 +1288,7 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
|
||||||
while (pos < end) {
|
while (pos < end) {
|
||||||
u16 info_id, elen;
|
u16 info_id, elen;
|
||||||
|
|
||||||
if (pos + 4 > end)
|
if (end - pos < 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info_id = WPA_GET_LE16(pos);
|
info_id = WPA_GET_LE16(pos);
|
||||||
|
@ -1296,7 +1296,7 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
|
||||||
elen = WPA_GET_LE16(pos);
|
elen = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
||||||
if (pos + elen > end) {
|
if (elen > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "ANQP: Invalid Query Request");
|
wpa_printf(MSG_DEBUG, "ANQP: Invalid Query Request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue