mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
qcacld-3.0: Validate Scan Default IEs
Currently the Scan Default IEs configured via the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES are not validated. As a result a buffer overread can occur when the Scan Default IEs are later referenced. To address this issue validate the Scan Default IEs before storing them. Change-Id: Ifd8739c96a9990f01ff159eb59a7e904f7b8c592 CRs-Fixed: 2154346
This commit is contained in:
parent
649e5047c7
commit
3b2abe930d
2 changed files with 92 additions and 26 deletions
|
|
@ -660,6 +660,27 @@ static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
|
|||
};
|
||||
#endif
|
||||
|
||||
bool hdd_is_ie_valid(const uint8_t *ie, size_t ie_len)
|
||||
{
|
||||
uint8_t elen;
|
||||
|
||||
while (ie_len) {
|
||||
if (ie_len < 2)
|
||||
return false;
|
||||
|
||||
elen = ie[1];
|
||||
ie_len -= 2;
|
||||
ie += 2;
|
||||
if (elen > ie_len)
|
||||
return false;
|
||||
|
||||
ie_len -= elen;
|
||||
ie += elen;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
|
||||
* @flags: Pointer to the flags to Add channel switch flag.
|
||||
|
|
@ -6142,6 +6163,56 @@ static int wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct hdd_context *hdd_ctx,
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
static int hdd_config_scan_default_ies(struct hdd_adapter *adapter,
|
||||
const struct nlattr *attr)
|
||||
{
|
||||
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
uint8_t *scan_ie;
|
||||
uint16_t scan_ie_len;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!attr)
|
||||
return 0;
|
||||
|
||||
scan_ie_len = nla_len(attr);
|
||||
hdd_debug("IE len %d session %d device mode %d",
|
||||
scan_ie_len, adapter->session_id, adapter->device_mode);
|
||||
|
||||
if (!scan_ie_len) {
|
||||
hdd_err("zero-length IE prohibited");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (scan_ie_len > MAX_DEFAULT_SCAN_IE_LEN) {
|
||||
hdd_err("IE length %d exceeds max of %d",
|
||||
scan_ie_len, MAX_DEFAULT_SCAN_IE_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scan_ie = nla_data(attr);
|
||||
if (!hdd_is_ie_valid(scan_ie, scan_ie_len)) {
|
||||
hdd_err("Invalid default scan IEs");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wlan_hdd_save_default_scan_ies(hdd_ctx, adapter,
|
||||
scan_ie, scan_ie_len))
|
||||
hdd_err("Failed to save default scan IEs");
|
||||
|
||||
if (adapter->device_mode == QDF_STA_MODE) {
|
||||
status = sme_set_default_scan_ie(hdd_ctx->hHal,
|
||||
adapter->session_id, scan_ie,
|
||||
scan_ie_len);
|
||||
if (QDF_STATUS_SUCCESS != status) {
|
||||
hdd_err("failed to set default scan IEs in sme: %d",
|
||||
status);
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
|
||||
* vendor command
|
||||
|
|
@ -6165,6 +6236,8 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
|
|||
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
||||
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
||||
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
|
||||
const struct nlattr *attr;
|
||||
int ret;
|
||||
int ret_val = 0;
|
||||
u32 modulated_dtim, override_li;
|
||||
u16 stats_avg_factor;
|
||||
|
|
@ -6177,8 +6250,6 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
|
|||
int access_policy = 0;
|
||||
char vendor_ie[SIR_MAC_MAX_IE_LENGTH + 2];
|
||||
bool vendor_ie_present = false, access_policy_present = false;
|
||||
uint16_t scan_ie_len = 0;
|
||||
uint8_t *scan_ie;
|
||||
struct sir_set_tx_rx_aggregation_size request;
|
||||
QDF_STATUS qdf_status;
|
||||
uint8_t retry, delay, enable_flag;
|
||||
|
|
@ -6421,30 +6492,10 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
|
|||
ret_val = hdd_enable_disable_ca_event(hdd_ctx, set_value);
|
||||
}
|
||||
|
||||
if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]) {
|
||||
scan_ie_len = nla_len(
|
||||
tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]);
|
||||
hdd_debug("Received default scan IE of len %d session %d device mode %d",
|
||||
scan_ie_len, adapter->session_id,
|
||||
adapter->device_mode);
|
||||
if (scan_ie_len && (scan_ie_len <= MAX_DEFAULT_SCAN_IE_LEN)) {
|
||||
scan_ie = (uint8_t *) nla_data(tb
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]);
|
||||
|
||||
if (wlan_hdd_save_default_scan_ies(hdd_ctx, adapter,
|
||||
scan_ie, scan_ie_len))
|
||||
hdd_err("Failed to save default scan IEs");
|
||||
|
||||
if (adapter->device_mode == QDF_STA_MODE) {
|
||||
status = sme_set_default_scan_ie(hdd_ctx->hHal,
|
||||
adapter->session_id, scan_ie,
|
||||
scan_ie_len);
|
||||
if (QDF_STATUS_SUCCESS != status)
|
||||
ret_val = -EPERM;
|
||||
}
|
||||
} else
|
||||
ret_val = -EPERM;
|
||||
}
|
||||
attr = tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES];
|
||||
ret = hdd_config_scan_default_ies(adapter, attr);
|
||||
if (ret)
|
||||
ret_val = ret;
|
||||
|
||||
if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] ||
|
||||
tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION]) {
|
||||
|
|
|
|||
|
|
@ -216,6 +216,21 @@ typedef enum {
|
|||
#define CFG_PROPAGATION_DELAY_BASE (64)
|
||||
#define CFG_AGG_RETRY_MIN (5)
|
||||
|
||||
/**
|
||||
* hdd_is_ie_valid() - Determine if an IE sequence is valid
|
||||
* @ie: Pointer to the IE buffer
|
||||
* @ie_len: Length of the IE buffer @ie
|
||||
*
|
||||
* This function validates that the IE sequence is valid by verifying
|
||||
* that the sum of the lengths of the embedded elements match the
|
||||
* length of the sequence.
|
||||
*
|
||||
* Note well that a 0-length IE sequence is considered valid.
|
||||
*
|
||||
* Return: true if the IE sequence is valid, false if it is invalid
|
||||
*/
|
||||
bool hdd_is_ie_valid(const uint8_t *ie, size_t ie_len);
|
||||
|
||||
struct cfg80211_bss *
|
||||
wlan_hdd_cfg80211_update_bss_db(struct hdd_adapter *adapter,
|
||||
struct csr_roam_info *roam_info);
|
||||
|
|
|
|||
Loading…
Reference in a new issue