GAS: Try to make buffer length determination easier for static analyzers
The received frame buffer was already verified to be long enough to include the Advertisement Protocol element and that element was verified to have a valid length value, but use of adv_proto[1] in another function may have been too difficult to figure out for analyzers. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
271ce71c7a
commit
0658a22ef1
1 changed files with 22 additions and 16 deletions
|
@ -404,14 +404,14 @@ static void gas_query_tx_comeback_req_delay(struct gas_query *gas,
|
|||
|
||||
static void gas_query_rx_initial(struct gas_query *gas,
|
||||
struct gas_query_pending *query,
|
||||
const u8 *adv_proto, const u8 *resp,
|
||||
size_t len, u16 comeback_delay)
|
||||
const u8 *adv_proto, size_t adv_proto_len,
|
||||
const u8 *resp, size_t len, u16 comeback_delay)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "GAS: Received initial response from "
|
||||
MACSTR " (dialog_token=%u comeback_delay=%u)",
|
||||
MAC2STR(query->addr), query->dialog_token, comeback_delay);
|
||||
|
||||
query->adv_proto = wpabuf_alloc_copy(adv_proto, 2 + adv_proto[1]);
|
||||
query->adv_proto = wpabuf_alloc_copy(adv_proto, adv_proto_len);
|
||||
if (query->adv_proto == NULL) {
|
||||
gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
|
||||
return;
|
||||
|
@ -436,9 +436,9 @@ static void gas_query_rx_initial(struct gas_query *gas,
|
|||
|
||||
static void gas_query_rx_comeback(struct gas_query *gas,
|
||||
struct gas_query_pending *query,
|
||||
const u8 *adv_proto, const u8 *resp,
|
||||
size_t len, u8 frag_id, u8 more_frags,
|
||||
u16 comeback_delay)
|
||||
const u8 *adv_proto, size_t adv_proto_len,
|
||||
const u8 *resp, size_t len, u8 frag_id,
|
||||
u8 more_frags, u16 comeback_delay)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "GAS: Received comeback response from "
|
||||
MACSTR " (dialog_token=%u frag_id=%u more_frags=%u "
|
||||
|
@ -447,7 +447,7 @@ static void gas_query_rx_comeback(struct gas_query *gas,
|
|||
more_frags, comeback_delay);
|
||||
eloop_cancel_timeout(gas_query_rx_comeback_timeout, gas, query);
|
||||
|
||||
if ((size_t) 2 + adv_proto[1] != wpabuf_len(query->adv_proto) ||
|
||||
if (adv_proto_len != wpabuf_len(query->adv_proto) ||
|
||||
os_memcmp(adv_proto, wpabuf_head(query->adv_proto),
|
||||
wpabuf_len(query->adv_proto)) != 0) {
|
||||
wpa_printf(MSG_DEBUG, "GAS: Advertisement Protocol changed "
|
||||
|
@ -516,6 +516,7 @@ int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
|
|||
u8 action, dialog_token, frag_id = 0, more_frags = 0;
|
||||
u16 comeback_delay, resp_len;
|
||||
const u8 *pos, *adv_proto;
|
||||
size_t adv_proto_len;
|
||||
int prot, pmf;
|
||||
unsigned int left;
|
||||
|
||||
|
@ -596,22 +597,26 @@ int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
|
|||
pos += 2;
|
||||
|
||||
/* Advertisement Protocol element */
|
||||
if (pos + 2 > data + len || pos + 2 + pos[1] > data + len) {
|
||||
adv_proto = pos;
|
||||
left = data + len - adv_proto;
|
||||
if (left < 2 || adv_proto[1] > left - 2) {
|
||||
wpa_printf(MSG_DEBUG, "GAS: No room for Advertisement "
|
||||
"Protocol element in the response from " MACSTR,
|
||||
MAC2STR(sa));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*pos != WLAN_EID_ADV_PROTO) {
|
||||
if (*adv_proto != WLAN_EID_ADV_PROTO) {
|
||||
wpa_printf(MSG_DEBUG, "GAS: Unexpected Advertisement "
|
||||
"Protocol element ID %u in response from " MACSTR,
|
||||
*pos, MAC2STR(sa));
|
||||
*adv_proto, MAC2STR(sa));
|
||||
return 0;
|
||||
}
|
||||
adv_proto_len = 2 + adv_proto[1];
|
||||
if (adv_proto_len > (size_t) (data + len - pos))
|
||||
return 0; /* unreachable due to an earlier check */
|
||||
|
||||
adv_proto = pos;
|
||||
pos += 2 + pos[1];
|
||||
pos += adv_proto_len;
|
||||
|
||||
/* Query Response Length */
|
||||
if (pos + 2 > data + len) {
|
||||
|
@ -635,11 +640,12 @@ int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
|
|||
}
|
||||
|
||||
if (action == WLAN_PA_GAS_COMEBACK_RESP)
|
||||
gas_query_rx_comeback(gas, query, adv_proto, pos, resp_len,
|
||||
frag_id, more_frags, comeback_delay);
|
||||
gas_query_rx_comeback(gas, query, adv_proto, adv_proto_len,
|
||||
pos, resp_len, frag_id, more_frags,
|
||||
comeback_delay);
|
||||
else
|
||||
gas_query_rx_initial(gas, query, adv_proto, pos, resp_len,
|
||||
comeback_delay);
|
||||
gas_query_rx_initial(gas, query, adv_proto, adv_proto_len,
|
||||
pos, resp_len, comeback_delay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue