qcacld-3.0: Avoid overflow of roam subcmd params
This is a qcacld-2.0 to qcacld-3.0 propagation. Currently when processing the QCA_NL80211_VENDOR_SUBCMD_ROAM vendor command, for the following roam commands there are input validation issues: QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BSSID_PREFS QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID Both of these commands have a "number of BSSIDs" attribute as well as a list of BSSIDs. However there is no validation that the number of BSSIDs provided won't overflow the destination buffer. In addition there is no validation that the number of BSSIDs actually provided matches the number of BSSIDs expected. To address these issues, for the above mentioned commands: * Verify that the expected number of BSSIDs doesn't exceed the maximum allowed number of BSSIDs * Verify that the actual number of BSSIDs supplied doesn't exceed the expected number of BSSIDs * Only process the actual number of supplied BSSIDs if it is less than the expected number of BSSIDs. Change-Id: Ifa6121ee1b1441ec415198897ef815b40cb5aff6 CRs-Fixed: 1092497
This commit is contained in:

committed by
qcabuildsw

parent
2f02ea1541
commit
075334eaec
@@ -2347,6 +2347,7 @@ __wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
|
|||||||
struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX + 1];
|
struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX + 1];
|
||||||
int rem, i;
|
int rem, i;
|
||||||
uint32_t buf_len = 0;
|
uint32_t buf_len = 0;
|
||||||
|
uint32_t count;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ENTER_DEV(dev);
|
ENTER_DEV(dev);
|
||||||
@@ -2517,14 +2518,24 @@ __wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
|
|||||||
hdd_err("attr num of preferred bssid failed");
|
hdd_err("attr num of preferred bssid failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
roam_params.num_bssid_favored = nla_get_u32(
|
count = nla_get_u32(
|
||||||
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID]);
|
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID]);
|
||||||
hdd_debug("Num of Preferred BSSID (%d)",
|
if (count > MAX_BSSID_FAVORED) {
|
||||||
roam_params.num_bssid_favored);
|
hdd_err("Preferred BSSID count %u exceeds max %u",
|
||||||
|
count, MAX_BSSID_FAVORED);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
hdd_debug("Num of Preferred BSSID (%d)", count);
|
||||||
i = 0;
|
i = 0;
|
||||||
nla_for_each_nested(curr_attr,
|
nla_for_each_nested(curr_attr,
|
||||||
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS],
|
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS],
|
||||||
rem) {
|
rem) {
|
||||||
|
|
||||||
|
if (i == count) {
|
||||||
|
hdd_warn("Ignoring excess Preferred BSSID");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (nla_parse(tb2,
|
if (nla_parse(tb2,
|
||||||
QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
|
QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
|
||||||
nla_data(curr_attr), nla_len(curr_attr),
|
nla_data(curr_attr), nla_len(curr_attr),
|
||||||
@@ -2553,6 +2564,10 @@ __wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
|
|||||||
roam_params.bssid_favored_factor[i]);
|
roam_params.bssid_favored_factor[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
if (i < count)
|
||||||
|
hdd_warn("Num Preferred BSSID %u less than expected %u",
|
||||||
|
i, count);
|
||||||
|
roam_params.num_bssid_favored = i;
|
||||||
sme_update_roam_params(pHddCtx->hHal, session_id,
|
sme_update_roam_params(pHddCtx->hHal, session_id,
|
||||||
roam_params, REASON_ROAM_SET_FAVORED_BSSID);
|
roam_params, REASON_ROAM_SET_FAVORED_BSSID);
|
||||||
break;
|
break;
|
||||||
@@ -2562,14 +2577,24 @@ __wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
|
|||||||
hdd_err("attr num of blacklist bssid failed");
|
hdd_err("attr num of blacklist bssid failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
roam_params.num_bssid_avoid_list = nla_get_u32(
|
count = nla_get_u32(
|
||||||
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID]);
|
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID]);
|
||||||
hdd_debug("Num of blacklist BSSID (%d)",
|
if (count > MAX_BSSID_AVOID_LIST) {
|
||||||
roam_params.num_bssid_avoid_list);
|
hdd_err("Blacklist BSSID count %u exceeds max %u",
|
||||||
|
count, MAX_BSSID_AVOID_LIST);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
hdd_debug("Num of blacklist BSSID (%d)", count);
|
||||||
i = 0;
|
i = 0;
|
||||||
nla_for_each_nested(curr_attr,
|
nla_for_each_nested(curr_attr,
|
||||||
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS],
|
tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS],
|
||||||
rem) {
|
rem) {
|
||||||
|
|
||||||
|
if (i == count) {
|
||||||
|
hdd_warn("Ignoring excess Blacklist BSSID");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (nla_parse(tb2,
|
if (nla_parse(tb2,
|
||||||
QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
|
QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
|
||||||
nla_data(curr_attr), nla_len(curr_attr),
|
nla_data(curr_attr), nla_len(curr_attr),
|
||||||
@@ -2590,6 +2615,10 @@ __wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
|
|||||||
roam_params.bssid_avoid_list[i].bytes));
|
roam_params.bssid_avoid_list[i].bytes));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
if (i < count)
|
||||||
|
hdd_warn("Num Blacklist BSSID %u less than expected %u",
|
||||||
|
i, count);
|
||||||
|
roam_params.num_bssid_avoid_list = i;
|
||||||
sme_update_roam_params(pHddCtx->hHal, session_id,
|
sme_update_roam_params(pHddCtx->hHal, session_id,
|
||||||
roam_params, REASON_ROAM_SET_BLACKLIST_BSSID);
|
roam_params, REASON_ROAM_SET_BLACKLIST_BSSID);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user