From 68834229f589e26bed0d95e6bd34d307774eca19 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 18 Jul 2018 19:06:14 +0530 Subject: [PATCH] qcacld-3.0: fix the beacon corruption in WMA beacon update msg When beacon is updated the host pass the gSchBeaconFrameBegin param to WMA to copy the beacon to WMI and pass the value to firmware. gSchBeaconFrameBegin is global so if we receive new beacon update in LIM before the WMA process the old beacon update the values in the global gSchBeaconFrameBegin are updated as per new beacon. So if there is change in beacon length the first WMA msg copy the wrong beacon data and send this corrupt date to firmware. To fix this instead of passing the global gSchBeaconFrameBegin fill the beacon date in the beacon update req itself. Change-Id: I6d196784470d9a2aeeaba76e12577f9f65012bac CRs-Fixed: 2272448 --- core/mac/inc/sir_mac_prot_def.h | 4 ++++ core/mac/src/pe/include/lim_session.h | 4 ---- core/mac/src/pe/lim/lim_session.c | 6 +++--- core/mac/src/pe/sch/sch_api.c | 15 ++++++++++++--- core/mac/src/pe/sch/sch_beacon_gen.c | 11 ++++++----- core/wma/inc/wma_if.h | 6 +++--- core/wma/src/wma_mgmt.c | 10 ++++++---- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index 8ae6117c6b..b64916de1c 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -644,6 +644,10 @@ #define SIR_MAC_VENDOR_AP_4_OUI "\x8C\xFD\xF0" #define SIR_MAC_VENDOR_AP_4_OUI_LEN 3 +/* Maximum allowable size of a beacon and probe rsp frame */ +#define SIR_MAX_BEACON_SIZE 512 +#define SIR_MAX_PROBE_RESP_SIZE 512 + /* / Status Code (present in Management response frames) enum */ typedef enum eSirMacStatusCodes { diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index eb224a4030..015d5691c1 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -59,10 +59,6 @@ typedef struct tagComebackTimerInfo { /* Maximum Number of WEP KEYS */ #define MAX_WEP_KEYS 4 -/* Maximum allowable size of a beacon frame */ -#define SCH_MAX_BEACON_SIZE 512 - -#define SCH_MAX_PROBE_RESP_SIZE 512 #define SCH_PROTECTION_RESET_TIME 4000 /*-------------------------------------------------------------------------- diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index 055ea7d64c..1bd27a324f 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -620,11 +620,11 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId, if (eSIR_INFRA_AP_MODE == bssType || eSIR_IBSS_MODE == bssType) { session_ptr->pSchProbeRspTemplate = - qdf_mem_malloc(SCH_MAX_PROBE_RESP_SIZE); + qdf_mem_malloc(SIR_MAX_PROBE_RESP_SIZE); session_ptr->pSchBeaconFrameBegin = - qdf_mem_malloc(SCH_MAX_BEACON_SIZE); + qdf_mem_malloc(SIR_MAX_BEACON_SIZE); session_ptr->pSchBeaconFrameEnd = - qdf_mem_malloc(SCH_MAX_BEACON_SIZE); + qdf_mem_malloc(SIR_MAX_BEACON_SIZE); if ((NULL == session_ptr->pSchProbeRspTemplate) || (NULL == session_ptr->pSchBeaconFrameBegin) || (NULL == session_ptr->pSchBeaconFrameEnd)) { diff --git a/core/mac/src/pe/sch/sch_api.c b/core/mac/src/pe/sch/sch_api.c index 3c251d0728..c844019295 100644 --- a/core/mac/src/pe/sch/sch_api.c +++ b/core/mac/src/pe/sch/sch_api.c @@ -166,7 +166,15 @@ QDF_STATUS sch_send_beacon_req(tpAniSirGlobal pMac, uint8_t *beaconPayload, pe_err("TimIeOffset:[%d]", beaconParams->TimIeOffset); #endif - beaconParams->beacon = beaconPayload; + if (size >= SIR_MAX_BEACON_SIZE) { + pe_err("beacon size (%d) exceed host limit %d", + size, SIR_MAX_BEACON_SIZE); + QDF_ASSERT(0); + qdf_mem_free(beaconParams); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(beaconParams->beacon, beaconPayload, size); + beaconParams->beaconLength = (uint32_t) size; msgQ.bodyptr = beaconParams; msgQ.bodyval = 0; @@ -346,7 +354,7 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac, nBytes += nPayload + sizeof(tSirMacMgmtHdr); /* Make sure we are not exceeding allocated len */ - if (nBytes > SCH_MAX_PROBE_RESP_SIZE) { + if (nBytes > SIR_MAX_PROBE_RESP_SIZE) { pe_err("nBytes %d greater than max size", nBytes); qdf_mem_free(addIE); return QDF_STATUS_E_FAILURE; @@ -394,7 +402,8 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac, pe_err("malloc failed for bytes %d", nBytes); } else { sir_copy_mac_addr(pprobeRespParams->bssId, psessionEntry->bssId); - pprobeRespParams->pProbeRespTemplate = pFrame2Hal; + qdf_mem_copy(pprobeRespParams->probeRespTemplate, + pFrame2Hal, nBytes); pprobeRespParams->probeRespTemplateLen = nBytes; qdf_mem_copy(pprobeRespParams->ucProxyProbeReqValidIEBmap, IeBitmap, (sizeof(uint32_t) * 8)); diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c index 53e2f68ee9..e728c7c012 100644 --- a/core/mac/src/pe/sch/sch_beacon_gen.c +++ b/core/mac/src/pe/sch/sch_beacon_gen.c @@ -331,7 +331,7 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) } n_status = dot11f_pack_beacon1(mac_ctx, bcn_1, ptr, - SCH_MAX_BEACON_SIZE - offset, &n_bytes); + SIR_MAX_BEACON_SIZE - offset, &n_bytes); if (DOT11F_FAILED(n_status)) { pe_err("Failed to packed a tDot11fBeacon1 (0x%08x)", n_status); @@ -589,8 +589,8 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) } n_status = dot11f_pack_beacon2(mac_ctx, bcn_2, - session->pSchBeaconFrameEnd, - SCH_MAX_BEACON_SIZE, &n_bytes); + session->pSchBeaconFrameEnd, + SIR_MAX_BEACON_SIZE, &n_bytes); if (DOT11F_FAILED(n_status)) { pe_err("Failed to packed a tDot11fBeacon2 (0x%08x)", n_status); @@ -630,8 +630,9 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) /* TODO: Append additional IE here. */ if (addn_ielen > 0) sch_append_addn_ie(mac_ctx, session, - session->pSchBeaconFrameEnd + n_bytes, - SCH_MAX_BEACON_SIZE, &n_bytes, addn_ie, addn_ielen); + session->pSchBeaconFrameEnd + n_bytes, + SIR_MAX_BEACON_SIZE, &n_bytes, + addn_ie, addn_ielen); session->schBeaconOffsetEnd = (uint16_t) n_bytes; extra_ie_len = n_bytes - extra_ie_offset; diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h index add632b402..e6bca95e33 100644 --- a/core/wma/inc/wma_if.h +++ b/core/wma/inc/wma_if.h @@ -722,7 +722,7 @@ typedef struct sBeaconGenParams { */ typedef struct { tSirMacAddr bssId; - uint8_t *beacon; + uint8_t beacon[SIR_MAX_BEACON_SIZE]; uint32_t beaconLength; uint32_t timIeOffset; uint16_t p2pIeOffset; @@ -733,13 +733,13 @@ typedef struct { /** * struct tSendProbeRespParams - send probe response parameters * @bssId: BSSID - * @pProbeRespTemplate: probe response template + * @probeRespTemplate: probe response template * @probeRespTemplateLen: probe response template length * @ucProxyProbeReqValidIEBmap: valid IE bitmap */ typedef struct sSendProbeRespParams { tSirMacAddr bssId; - uint8_t *pProbeRespTemplate; + uint8_t probeRespTemplate[SIR_MAX_PROBE_RESP_SIZE]; uint32_t probeRespTemplateLen; uint32_t ucProxyProbeReqValidIEBmap[8]; } tSendProbeRespParams, *tpSendProbeRespParams; diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index fcba5a0de0..16b6e5e158 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2538,11 +2538,11 @@ static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma, adjusted_tsf_le = cpu_to_le64(0ULL - wma->interfaces[vdev_id].tsfadjust); /* Update the timstamp in the probe response buffer with adjusted TSF */ - wh = (struct ieee80211_frame *)probe_rsp_info->pProbeRespTemplate; + wh = (struct ieee80211_frame *)probe_rsp_info->probeRespTemplate; A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le)); params.prb_rsp_template_len = probe_rsp_info->probeRespTemplateLen; - params.prb_rsp_template_frm = probe_rsp_info->pProbeRespTemplate; + params.prb_rsp_template_frm = probe_rsp_info->probeRespTemplate; return wmi_unified_probe_rsp_tmpl_send_cmd(wma->wmi_handle, vdev_id, ¶ms); @@ -2761,7 +2761,8 @@ int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event, qdf_spin_lock_bh(&bcn->lock); qdf_mem_zero(&bcn_info, sizeof(bcn_info)); - bcn_info.beacon = qdf_nbuf_data(bcn->buf); + qdf_mem_copy(bcn_info.beacon, + qdf_nbuf_data(bcn->buf), bcn->len); bcn_info.p2pIeOffset = bcn->p2p_ie_offset; bcn_info.beaconLength = bcn->len; bcn_info.timIeOffset = bcn->tim_ie_offset; @@ -2815,7 +2816,8 @@ void wma_send_probe_rsp_tmpl(tp_wma_handle wma, return; } - probe_rsp = (struct sAniProbeRspStruct *) (probe_rsp_info->pProbeRespTemplate); + probe_rsp = (struct sAniProbeRspStruct *) + (probe_rsp_info->probeRespTemplate); if (!probe_rsp) { WMA_LOGE(FL("probe_rsp is NULL")); return;