qcacld-3.0: Ensure conn_state session_id in bounds

Attempting to flush the powersave timer on an adapter with an invalid
session_id leads to an out-of-bounds access when checking the station
context's connection state. Only flush powersave timers for adapters
with valid session_ids. Additionally, add debug asserts for invalid
session_id's in the other connection state checking functions too.

Change-Id: Iacd2f97b01d7f6901d402908304a43c2c20d2380
CRs-Fixed: 2281219
This commit is contained in:
Dustin Brown 2018-07-18 15:04:33 -07:00 • committed by nshrivas
commit 6619bc276c
3 changed files with 53 additions and 30 deletions

View file

@ -1675,8 +1675,12 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
}
/* flush any pending powersave timers */
hdd_for_each_adapter(hdd_ctx, adapter)
hdd_for_each_adapter(hdd_ctx, adapter) {
if (adapter->session_id >= MAX_NUMBER_OF_ADAPTERS)
continue;
sme_ps_timer_flush_sync(mac_handle, adapter->session_id);
}
/*
* Suspend IPA early before proceeding to suspend other entities like

View file

@ -341,6 +341,10 @@ QDF_STATUS sme_enable_sta_ps_check(tpAniSirGlobal mac_ctx, uint32_t session_id)
{
struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
QDF_BUG(session_id < CSR_ROAM_SESSION_MAX);
if (session_id >= CSR_ROAM_SESSION_MAX)
return QDF_STATUS_E_INVAL;
/* Check if Sta Ps is enabled. */
if (!ps_global_info->ps_enabled) {
sme_debug("Cannot initiate PS. PS is disabled in ini");
@ -356,8 +360,8 @@ QDF_STATUS sme_enable_sta_ps_check(tpAniSirGlobal mac_ctx, uint32_t session_id)
session_id);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
return QDF_STATUS_SUCCESS;
}
/**
@ -391,6 +395,10 @@ QDF_STATUS sme_ps_timer_flush_sync(tHalHandle hal, uint8_t session_id)
struct sEnablePsParams *req;
t_wma_handle *wma;
QDF_BUG(session_id < CSR_ROAM_SESSION_MAX);
if (session_id >= CSR_ROAM_SESSION_MAX)
return QDF_STATUS_E_INVAL;
status = sme_enable_sta_ps_check(mac_ctx, session_id);
if (QDF_IS_STATUS_ERROR(status)) {
sme_debug("Power save not allowed for vdev id %d", session_id);

View file

@ -623,33 +623,42 @@ bool csr_is_bss_id_equal(tSirBssDescription *pSirBssDesc1,
return fEqual;
}
bool csr_is_conn_state_connected_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
static bool csr_is_conn_state(tpAniSirGlobal mac_ctx, uint32_t session_id,
eCsrConnectState state)
{
return eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED ==
pMac->roam.roamSession[sessionId].connectState;
QDF_BUG(session_id < CSR_ROAM_SESSION_MAX);
if (session_id >= CSR_ROAM_SESSION_MAX)
return false;
return mac_ctx->roam.roamSession[session_id].connectState == state;
}
bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal pMac,
uint32_t sessionId)
bool csr_is_conn_state_connected_ibss(tpAniSirGlobal mac_ctx,
uint32_t session_id)
{
return eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED ==
pMac->roam.roamSession[sessionId].connectState;
return csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED);
}
bool csr_is_conn_state_connected_infra(tpAniSirGlobal pMac, uint32_t sessionId)
bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal mac_ctx,
uint32_t session_id)
{
return eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
pMac->roam.roamSession[sessionId].connectState;
return csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED);
}
bool csr_is_conn_state_connected_infra(tpAniSirGlobal mac_ctx,
uint32_t session_id)
{
return csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED);
}
bool csr_is_conn_state_connected(tpAniSirGlobal pMac, uint32_t sessionId)
{
if (csr_is_conn_state_connected_ibss(pMac, sessionId)
|| csr_is_conn_state_connected_infra(pMac, sessionId)
|| csr_is_conn_state_connected_wds(pMac, sessionId))
return true;
else
return false;
return csr_is_conn_state_connected_ibss(pMac, sessionId) ||
csr_is_conn_state_connected_infra(pMac, sessionId) ||
csr_is_conn_state_connected_wds(pMac, sessionId);
}
bool csr_is_conn_state_infra(tpAniSirGlobal pMac, uint32_t sessionId)
@ -663,25 +672,27 @@ bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
csr_is_conn_state_disconnected_ibss(pMac, sessionId);
}
bool csr_is_conn_state_connected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
bool csr_is_conn_state_connected_wds(tpAniSirGlobal mac_ctx,
uint32_t session_id)
{
return eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED ==
pMac->roam.roamSession[sessionId].connectState;
return csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED);
}
bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal pMac,
uint32_t sessionId)
bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal mac_ctx,
uint32_t session_id)
{
return (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
pMac->roam.roamSession[sessionId].connectState) ||
(eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
pMac->roam.roamSession[sessionId].connectState);
return csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED) ||
csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED);
}
bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal mac_ctx,
uint32_t session_id)
{
return eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED ==
pMac->roam.roamSession[sessionId].connectState;
return csr_is_conn_state(mac_ctx, session_id,
eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED);
}
bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId)