mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 10:04:12 +08:00
wifi: mac80211: disambiguate element parsing errors
Let the element parsing function return what kind of error was encountered, as a bitmap, even if nothing currently checks for which specific error it was, we'll use it later. Link: https://msgid.link/20240129200652.1a69f2a31ec7.I55b86561d64e7ef1504c73f6f2813c33030c8136@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
676259100c
commit
3552a22880
@ -1666,6 +1666,13 @@ struct ieee80211_csa_ie {
|
||||
u32 max_switch_time;
|
||||
};
|
||||
|
||||
enum ieee80211_elems_parse_error {
|
||||
IEEE80211_PARSE_ERR_INVALID_END = BIT(0),
|
||||
IEEE80211_PARSE_ERR_DUP_ELEM = BIT(1),
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE = BIT(2),
|
||||
IEEE80211_PARSE_ERR_UNEXPECTED_ELEM = BIT(3),
|
||||
};
|
||||
|
||||
/* Parsed Information Elements */
|
||||
struct ieee802_11_elems {
|
||||
const u8 *ie_start;
|
||||
@ -1776,8 +1783,8 @@ struct ieee802_11_elems {
|
||||
struct ieee80211_mle_per_sta_profile *prof;
|
||||
size_t sta_prof_len;
|
||||
|
||||
/* whether a parse error occurred while retrieving these elements */
|
||||
bool parse_error;
|
||||
/* whether/which parse error occurred while retrieving these elements */
|
||||
u8 parse_error;
|
||||
|
||||
/*
|
||||
* scratch buffer that can be used for various element parsing related
|
||||
|
@ -1063,7 +1063,7 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
|
||||
for_each_element(elem, params->start, params->len) {
|
||||
const struct element *subelem;
|
||||
bool elem_parse_failed;
|
||||
u8 elem_parse_failed;
|
||||
u8 id = elem->id;
|
||||
u8 elen = elem->datalen;
|
||||
const u8 *pos = elem->data;
|
||||
@ -1119,7 +1119,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
* that if the content gets bigger it might be needed more than once
|
||||
*/
|
||||
if (test_bit(id, seen_elems)) {
|
||||
elems->parse_error = true;
|
||||
elems->parse_error |=
|
||||
IEEE80211_PARSE_ERR_DUP_ELEM;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -1128,19 +1129,21 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (calc_crc && id < 64 && (params->filter & (1ULL << id)))
|
||||
crc = crc32_be(crc, pos - 2, elen + 2);
|
||||
|
||||
elem_parse_failed = false;
|
||||
elem_parse_failed = 0;
|
||||
|
||||
switch (id) {
|
||||
case WLAN_EID_LINK_ID:
|
||||
if (elen + 2 < sizeof(struct ieee80211_tdls_lnkie)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->lnk_id = (void *)(pos - 2);
|
||||
break;
|
||||
case WLAN_EID_CHAN_SWITCH_TIMING:
|
||||
if (elen < sizeof(struct ieee80211_ch_switch_timing)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->ch_sw_timing = (void *)pos;
|
||||
@ -1161,14 +1164,16 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= 1)
|
||||
elems->ds_params = pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_TIM:
|
||||
if (elen >= sizeof(struct ieee80211_tim_ie)) {
|
||||
elems->tim = (void *)pos;
|
||||
elems->tim_len = elen;
|
||||
} else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_VENDOR_SPECIFIC:
|
||||
if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
|
||||
@ -1198,7 +1203,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= 1)
|
||||
elems->erp_info = pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_EXT_SUPP_RATES:
|
||||
elems->ext_supp_rates = pos;
|
||||
@ -1210,7 +1216,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(struct ieee80211_ht_cap))
|
||||
elems->ht_cap_elem = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_HT_OPERATION:
|
||||
if (params->mode < IEEE80211_CONN_MODE_HT)
|
||||
@ -1218,7 +1225,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(struct ieee80211_ht_operation))
|
||||
elems->ht_operation = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_VHT_CAPABILITY:
|
||||
if (params->mode < IEEE80211_CONN_MODE_VHT)
|
||||
@ -1226,7 +1234,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(struct ieee80211_vht_cap))
|
||||
elems->vht_cap_elem = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_VHT_OPERATION:
|
||||
if (params->mode < IEEE80211_CONN_MODE_VHT)
|
||||
@ -1237,7 +1246,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
crc = crc32_be(crc, pos - 2, elen + 2);
|
||||
break;
|
||||
}
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_OPMODE_NOTIF:
|
||||
if (params->mode < IEEE80211_CONN_MODE_VHT)
|
||||
@ -1248,7 +1258,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
crc = crc32_be(crc, pos - 2, elen + 2);
|
||||
break;
|
||||
}
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_MESH_ID:
|
||||
elems->mesh_id = pos;
|
||||
@ -1258,7 +1269,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(struct ieee80211_meshconf_ie))
|
||||
elems->mesh_config = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_PEER_MGMT:
|
||||
elems->peering = pos;
|
||||
@ -1284,18 +1296,21 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(struct ieee80211_rann_ie))
|
||||
elems->rann = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_CHANNEL_SWITCH:
|
||||
if (elen != sizeof(struct ieee80211_channel_sw_ie)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->ch_switch_ie = (void *)pos;
|
||||
break;
|
||||
case WLAN_EID_EXT_CHANSWITCH_ANN:
|
||||
if (elen != sizeof(struct ieee80211_ext_chansw_ie)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->ext_chansw_ie = (void *)pos;
|
||||
@ -1304,7 +1319,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (params->mode < IEEE80211_CONN_MODE_HT)
|
||||
break;
|
||||
if (elen != sizeof(struct ieee80211_sec_chan_offs_ie)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->sec_chan_offs = (void *)pos;
|
||||
@ -1312,7 +1328,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
case WLAN_EID_CHAN_SWITCH_PARAM:
|
||||
if (elen <
|
||||
sizeof(*elems->mesh_chansw_params_ie)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->mesh_chansw_params_ie = (void *)pos;
|
||||
@ -1320,9 +1337,16 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
|
||||
if (params->mode < IEEE80211_CONN_MODE_VHT)
|
||||
break;
|
||||
if (!params->action ||
|
||||
elen < sizeof(*elems->wide_bw_chansw_ie)) {
|
||||
elem_parse_failed = true;
|
||||
|
||||
if (!params->action) {
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_UNEXPECTED_ELEM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (elen < sizeof(*elems->wide_bw_chansw_ie)) {
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->wide_bw_chansw_ie = (void *)pos;
|
||||
@ -1331,7 +1355,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (params->mode < IEEE80211_CONN_MODE_VHT)
|
||||
break;
|
||||
if (params->action) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_UNEXPECTED_ELEM;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@ -1345,7 +1370,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
elems->wide_bw_chansw_ie =
|
||||
(void *)subelem->data;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
}
|
||||
|
||||
if (params->mode < IEEE80211_CONN_MODE_EHT)
|
||||
@ -1361,7 +1387,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
edatalen))
|
||||
elems->bandwidth_indication = edata;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
}
|
||||
break;
|
||||
case WLAN_EID_COUNTRY:
|
||||
@ -1370,7 +1397,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
break;
|
||||
case WLAN_EID_PWR_CONSTRAINT:
|
||||
if (elen != 1) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->pwr_constr_elem = pos;
|
||||
@ -1382,7 +1410,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
* tag (0x00).
|
||||
*/
|
||||
if (elen < 4) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1391,7 +1420,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
break;
|
||||
|
||||
if (elen != 6) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1402,7 +1432,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
break;
|
||||
case WLAN_EID_ADDBA_EXT:
|
||||
if (elen < sizeof(struct ieee80211_addba_ext_ie)) {
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
}
|
||||
elems->addba_ext_ie = (void *)pos;
|
||||
@ -1411,7 +1442,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(struct ieee80211_timeout_interval_ie))
|
||||
elems->timeout_int = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_BSS_MAX_IDLE_PERIOD:
|
||||
if (elen >= sizeof(*elems->max_idle_period_ie))
|
||||
@ -1444,7 +1476,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen >= sizeof(*elems->s1g_capab))
|
||||
elems->s1g_capab = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_S1G_OPERATION:
|
||||
if (params->mode != IEEE80211_CONN_MODE_S1G)
|
||||
@ -1452,7 +1485,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen == sizeof(*elems->s1g_oper))
|
||||
elems->s1g_oper = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_S1G_BCN_COMPAT:
|
||||
if (params->mode != IEEE80211_CONN_MODE_S1G)
|
||||
@ -1460,7 +1494,8 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen == sizeof(*elems->s1g_bcn_compat))
|
||||
elems->s1g_bcn_compat = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
case WLAN_EID_AID_RESPONSE:
|
||||
if (params->mode != IEEE80211_CONN_MODE_S1G)
|
||||
@ -1468,20 +1503,21 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params,
|
||||
if (elen == sizeof(struct ieee80211_aid_response_ie))
|
||||
elems->aid_resp = (void *)pos;
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
elem_parse_failed =
|
||||
IEEE80211_PARSE_ERR_BAD_ELEM_SIZE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (elem_parse_failed)
|
||||
elems->parse_error = true;
|
||||
elems->parse_error |= elem_parse_failed;
|
||||
else
|
||||
__set_bit(id, seen_elems);
|
||||
}
|
||||
|
||||
if (!for_each_element_completed(elem, params->start, params->len))
|
||||
elems->parse_error = true;
|
||||
elems->parse_error |= IEEE80211_PARSE_ERR_INVALID_END;
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user