diff --git a/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c b/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c index 7d181b290ad5..243b3dbfcf24 100644 --- a/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c +++ b/drivers/staging/qcacld-3.0/core/bmi/src/ol_fw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -376,18 +376,22 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file, || chip_id == AR6320_REV1_3_VERSION || chip_id == AR6320_REV2_1_VERSION)) { + bin_off = sizeof(SIGN_HEADER_T); status = bmi_sign_stream_start(address, (uint8_t *)fw_entry->data, - sizeof(SIGN_HEADER_T), ol_ctx); + bin_off, ol_ctx); if (status != EOK) { BMI_ERR("unable to start sign stream"); status = -EINVAL; goto end; } - bin_off = sizeof(SIGN_HEADER_T); - bin_len = sign_header->rampatch_len - - sizeof(SIGN_HEADER_T); + bin_len = sign_header->rampatch_len - bin_off; + if (bin_len <= 0 || bin_len > fw_entry_size - bin_off) { + BMI_ERR("Invalid sign header"); + status = -EINVAL; + goto end; + } } else { bin_sign = false; bin_off = 0; @@ -418,7 +422,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file, bin_off += bin_len; bin_len = sign_header->total_len - sign_header->rampatch_len; - if (bin_len > 0) { + if (bin_len > 0 && bin_len <= fw_entry_size - bin_off) { status = bmi_sign_stream_start(0, (uint8_t *)fw_entry->data + bin_off, bin_len, ol_ctx); diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h b/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h index b3c036bea771..c9a3448c7d49 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h +++ b/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2014-2015, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2014-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1815,6 +1815,8 @@ enum { #define IEEE80211_CCMP_HEADERLEN 8 #define IEEE80211_CCMP_MICLEN 8 +#define WLAN_IEEE80211_GCMP_HEADERLEN 8 +#define WLAN_IEEE80211_GCMP_MICLEN 16 /* * 802.11w defines a MMIE chunk to be attached at the end of diff --git a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h index 950751aa9f4e..85dd80954b9f 100644 --- a/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h +++ b/drivers/staging/qcacld-3.0/core/dp/ol/inc/ol_htt_rx_api.h @@ -815,6 +815,12 @@ void htt_rx_msdu_buff_replenish(htt_pdev_handle pdev); * Return: number of buffers actually replenished */ int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num); +#else +static inline +int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num) +{ + return 0; +} #endif /** diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c index 4496b21eabbf..60ec62624669 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c @@ -316,6 +316,26 @@ void ol_rx_frag_send_pktlog_event(struct ol_txrx_pdev_t *pdev, #endif +#ifndef CONFIG_HL_SUPPORT +static int ol_rx_frag_get_inord_msdu_cnt(qdf_nbuf_t rx_ind_msg) +{ + uint32_t *msg_word; + uint8_t *rx_ind_data; + uint32_t msdu_cnt; + + rx_ind_data = qdf_nbuf_data(rx_ind_msg); + msg_word = (uint32_t *)rx_ind_data; + msdu_cnt = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1)); + + return msdu_cnt; +} +#else +static int ol_rx_frag_get_inord_msdu_cnt(qdf_nbuf_t rx_ind_msg) +{ + return 0; +} +#endif + /* * Process incoming fragments */ @@ -353,7 +373,10 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev, * separate from normal frames */ ol_rx_reorder_flush_frag(htt_pdev, peer, tid, seq_num_start); + } else { + msdu_count = ol_rx_frag_get_inord_msdu_cnt(rx_frag_ind_msg); } + pktlog_bit = (htt_rx_amsdu_rx_in_order_get_pktlog(rx_frag_ind_msg) == 0x01); ret = htt_rx_frag_pop(htt_pdev, rx_frag_ind_msg, &head_msdu, @@ -389,7 +412,11 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev, htt_rx_desc_frame_free(htt_pdev, head_msdu); } /* request HTT to provide new rx MSDU buffers for the target to fill. */ - htt_rx_msdu_buff_replenish(htt_pdev); + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev) && + !pdev->cfg.is_high_latency) + htt_rx_msdu_buff_in_order_replenish(htt_pdev, msdu_count); + else + htt_rx_msdu_buff_replenish(htt_pdev); } /* diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h index c3ab9bd9be2f..be273c924073 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_main.h @@ -1368,8 +1368,6 @@ struct hdd_adapter_s { /* TODO Move this to sta Ctx */ struct wireless_dev wdev; - struct cfg80211_scan_request *request; - struct cfg80211_scan_request *vendor_request; /** ops checks if Opportunistic Power Save is Enable or Not * ctw stores ctWindow value once we receive Opps command from @@ -1526,6 +1524,8 @@ struct hdd_adapter_s { struct delayed_work acs_pending_work; struct work_struct scan_block_work; + qdf_list_t blocked_scan_request_q; + qdf_mutex_t blocked_scan_request_q_lock; #ifdef MSM_PLATFORM unsigned long prev_rx_packets; unsigned long prev_tx_packets; diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c index a85844c34cb3..85845d622f35 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_assoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -62,6 +62,7 @@ #include "wlan_hdd_napi.h" #include #include "wlan_hdd_tsf.h" +#include "wlan_hdd_scan.h" /* These are needed to recognize WPA and RSN suite types */ #define HDD_WPA_OUI_SIZE 4 @@ -949,6 +950,8 @@ static void hdd_save_bss_info(hdd_adapter_t *adapter, } else { hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false; } + qdf_mem_zero(&hdd_sta_ctx->ibss_enc_key, + sizeof(hdd_sta_ctx->ibss_enc_key)); } /** @@ -1754,6 +1757,7 @@ static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter, hdd_wmm_adapter_clear(pAdapter); sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId); + sme_reset_key(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId); if (hdd_remove_beacon_filter(pAdapter) != 0) hdd_err("hdd_remove_beacon_filter() failed"); @@ -1934,6 +1938,9 @@ QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter, #endif if (sta_state == OL_TXRX_PEER_STATE_AUTH) { + /* Reset scan reject params on successful set key */ + hdd_debug("Reset scan reject params"); + hdd_init_scan_reject_params(pAdapter->pHddCtx); #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL /* make sure event is reset */ INIT_COMPLETION(pAdapter->sta_authorized_event); @@ -2605,6 +2612,12 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, return QDF_STATUS_E_NULL_VALUE; } + /* + * reset scan reject params if connection is success or we received + * final failure from CSR after trying with all APs. + */ + hdd_reset_scan_reject_params(pHddCtx, roamStatus, roamResult); + /* * Enable roaming on other STA iface except this one. * Firmware dosent support connection on one STA iface while @@ -3158,7 +3171,9 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, pRoamInfo ? pRoamInfo->bssid.bytes : pWextState->req_bssId.bytes); - connect_timeout = true; + if (roamResult != + eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE) + connect_timeout = true; } /* @@ -3232,6 +3247,8 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, timeout_reason); } hdd_clear_roam_profile_ie(pAdapter); + sme_reset_key(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); } else if ((eCSR_ROAM_CANCELLED == roamStatus && !hddDisconInProgress)) { hdd_connect_result(dev, diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c index 3a58b17fb475..05b3e16a147a 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c @@ -4930,6 +4930,8 @@ static int __wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy, qdf_mem_copy(local_pmk, data, data_len); sme_roam_set_psk_pmk(WLAN_HDD_GET_HAL_CTX(hdd_adapter_ptr), hdd_adapter_ptr->sessionId, local_pmk, data_len); + qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE); + return 0; } @@ -15411,6 +15413,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, default: hdd_err("Unsupported cipher type: %u", params->cipher); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EOPNOTSUPP; } @@ -15431,6 +15434,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, /* if a key is already installed, block all subsequent ones */ if (pAdapter->sessionCtx.station.ibss_enc_key_installed) { hdd_debug("IBSS key installed already"); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return 0; } @@ -15441,6 +15445,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, if (0 != status) { hdd_err("sme_roam_set_key failed, status: %d", status); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } /*Save the keys here and call sme_roam_set_key for setting @@ -15449,6 +15454,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, &setKey, sizeof(tCsrRoamSetKey)); pAdapter->sessionCtx.station.ibss_enc_key_installed = 1; + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return status; } if ((pAdapter->device_mode == QDF_SAP_MODE) || @@ -15511,9 +15517,11 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, pAdapter->sessionId, &setKey); if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) { hdd_debug("Update PreAuth Key success"); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return 0; } else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) { hdd_err("Update PreAuth Key failed"); + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } @@ -15525,6 +15533,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, hdd_err("sme_roam_set_key failed, status: %d", status); pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } @@ -15558,10 +15567,12 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status); pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); return -EINVAL; } } } + qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); EXIT(); return 0; } @@ -20005,6 +20016,8 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, sme_set_del_pmkid_cache(halHandle, pAdapter->sessionId, &pmk_cache, true); + qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); + EXIT(); return QDF_IS_STATUS_SUCCESS(result) ? 0 : -EINVAL; } @@ -20095,6 +20108,8 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, sme_set_del_pmkid_cache(halHandle, pAdapter->sessionId, &pmk_cache, false); + qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); + EXIT(); return status; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c index c78c6676f17b..573057216642 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c @@ -8420,6 +8420,12 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, if (pIe != NULL) { pIe++; + if (pIe[0] > SIR_MAC_RATESET_EID_MAX) { + hdd_err("Invalid supported rates %d", + pIe[0]); + ret = -EINVAL; + goto error; + } pConfig->supported_rates.numRates = pIe[0]; pIe++; for (i = 0; @@ -8436,6 +8442,12 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, WLAN_EID_EXT_SUPP_RATES); if (pIe != NULL) { pIe++; + if (pIe[0] > SIR_MAC_RATESET_EID_MAX) { + hdd_err("Invalid supported rates %d", + pIe[0]); + ret = -EINVAL; + goto error; + } pConfig->extended_rates.numRates = pIe[0]; pIe++; for (i = 0; i < pConfig->extended_rates.numRates; i++) { diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c index 6e9b7bc50fce..9bb3bdfbad4d 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -497,10 +497,11 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb, msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN)); if (!rc) hdd_err("Timeout occurred while waiting for abortscan"); - } else { - cds_flush_work(&adapter->scan_block_work); - hdd_debug("Scan is not Pending from user"); } + cds_flush_work(&adapter->scan_block_work); + /* Need to clean up blocked scan request */ + wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work); + hdd_debug("Scan is not Pending from user"); /* * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective * of return status of hdd_stop call, kernel resets the IFF_UP @@ -4286,6 +4287,9 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type, } INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); + qdf_list_create(&adapter->blocked_scan_request_q, + CFG_MAX_SCAN_COUNT_MAX); + qdf_mutex_create(&adapter->blocked_scan_request_q_lock); cfgState = WLAN_HDD_GET_CFG_STATE_PTR(adapter); mutex_init(&cfgState->remain_on_chan_ctx_lock); @@ -4364,6 +4368,9 @@ QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, hdd_bus_bw_compute_timer_stop(hdd_ctx); cancel_work_sync(&hdd_ctx->bus_bw_work); + qdf_list_destroy(&adapter->blocked_scan_request_q); + qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); + /* cleanup adapter */ cds_clear_concurrency_mode(adapter->device_mode); hdd_cleanup_adapter(hdd_ctx, adapterNode->pAdapter, rtnl_held); @@ -4659,6 +4666,12 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, wlan_hdd_tdls_exit(adapter); wlan_hdd_cleanup_remain_on_channel_ctx(adapter); hdd_clear_fils_connection_info(adapter); + qdf_ret_status = sme_roam_del_pmkid_from_cache( + hdd_ctx->hHal, + adapter->sessionId, + NULL, true); + if (QDF_IS_STATUS_ERROR(qdf_ret_status)) + hdd_err("Cannot flush PMKIDCache"); #ifdef WLAN_OPEN_SOURCE cancel_work_sync(&adapter->ipv4NotifierWorkQueue); @@ -8253,6 +8266,8 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) hdd_adapter_t *adapter = NULL; void *cds_context = NULL; int i; + struct ieee80211_mgmt *mgmt = + (struct ieee80211_mgmt *)frame_ind->frameBuf; /* Get the global VOSS context.*/ cds_context = cds_get_global_context(); @@ -8266,6 +8281,11 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) if (0 != wlan_hdd_validate_context(hdd_ctx)) return; + if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) { + hdd_err(" Invalid frame length"); + return; + } + if (SME_SESSION_ID_ANY == frame_ind->sessionId) { for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { adapter = @@ -12740,6 +12760,11 @@ void hdd_set_roaming_in_progress(bool value) hdd_ctx->roaming_in_progress = value; hdd_debug("Roaming in Progress set to %d", value); + if (!hdd_ctx->roaming_in_progress) { + /* Reset scan reject params on successful roam complete */ + hdd_debug("Reset scan reject params"); + hdd_init_scan_reject_params(hdd_ctx); + } } /** diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c index 3cc55703d8f8..cf46c118be55 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ocb.c @@ -1663,6 +1663,12 @@ static int __wlan_hdd_cfg80211_dcc_get_stats(struct wiphy *wiphy, request_array = nla_data( tb[QCA_WLAN_VENDOR_ATTR_DCC_GET_STATS_REQUEST_ARRAY]); + /* Check channel count. Per 11p spec, max 2 channels allowed */ + if (!channel_count || channel_count > TGT_NUM_OCB_CHANNELS) { + hdd_err("Invalid channel_count %d", channel_count); + return -EINVAL; + } + hdd_request = hdd_request_alloc(¶ms); if (!hdd_request) { hdd_err("Request allocation failure"); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c index d58b310070b9..c5e657947483 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_power.c @@ -1654,10 +1654,8 @@ QDF_STATUS hdd_wlan_re_init(void) /* Restart all adapters */ hdd_start_all_adapters(pHddCtx); - pHddCtx->last_scan_reject_session_id = 0xFF; - pHddCtx->last_scan_reject_reason = 0; - pHddCtx->last_scan_reject_timestamp = 0; - pHddCtx->scan_reject_cnt = 0; + /* init the scan reject params */ + hdd_init_scan_reject_params(pHddCtx); hdd_set_roaming_in_progress(false); complete(&pAdapter->roaming_comp_var); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c index 26aea5a2e6db..dd8e313ae605 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.c @@ -437,6 +437,32 @@ static int hdd_add_scan_event_from_ies(struct hdd_scan_info *scanInfo, return 0; } +void hdd_init_scan_reject_params(hdd_context_t *hdd_ctx) +{ + if (hdd_ctx) { + hdd_ctx->last_scan_reject_timestamp = 0; + hdd_ctx->last_scan_reject_session_id = 0xFF; + hdd_ctx->last_scan_reject_reason = 0; + hdd_ctx->scan_reject_cnt = 0; + } + + return; +} + +void hdd_reset_scan_reject_params(hdd_context_t *hdd_ctx, + eRoamCmdStatus roam_status, + eCsrRoamResult roam_result) +{ + + if ((roam_status == eCSR_ROAM_ASSOCIATION_FAILURE) || + (roam_status == eCSR_ROAM_CANCELLED) || + (roam_result == eCSR_ROAM_RESULT_ASSOCIATED)) { + hdd_debug("Reset scan reject params"); + hdd_init_scan_reject_params(hdd_ctx); + } + + return; +} /** * hdd_indicate_scan_result() - indicate scan results @@ -1629,35 +1655,35 @@ static void __wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) hdd_adapter_t *adapter = container_of(work, hdd_adapter_t, scan_block_work); struct cfg80211_scan_request *request; - hdd_context_t *hdd_ctx; + struct hdd_scan_req *blocked_scan_req; + qdf_list_node_t *node = NULL; if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { hdd_err("HDD adapter context is invalid"); return; } - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (0 != wlan_hdd_validate_context(hdd_ctx)) - return; + qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock); - request = adapter->request; - if (request) { + while (!qdf_list_empty(&adapter->blocked_scan_request_q)) { + qdf_list_remove_front(&adapter->blocked_scan_request_q, + &node); + blocked_scan_req = qdf_container_of(node, struct hdd_scan_req, + node); + request = blocked_scan_req->scan_request; request->n_ssids = 0; request->n_channels = 0; - - hdd_err("##In DFS Master mode. Scan aborted. Null result sent"); - hdd_cfg80211_scan_done(adapter, request, true); - adapter->request = NULL; + if (blocked_scan_req->source == NL_SCAN) { + hdd_err("Scan aborted. Null result sent"); + hdd_cfg80211_scan_done(adapter, request, true); + } else { + hdd_err("Vendor scan aborted. Null result sent"); + hdd_vendor_scan_callback(adapter, request, true); + } + qdf_mem_free(blocked_scan_req); } - request = adapter->vendor_request; - if (request) { - request->n_ssids = 0; - request->n_channels = 0; - hdd_err("In DFS Master mode. Scan aborted. Null result sent"); - hdd_vendor_scan_callback(adapter, request, true); - adapter->vendor_request = NULL; - } + qdf_mutex_release(&adapter->blocked_scan_request_q_lock); } void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) @@ -1923,6 +1949,43 @@ static void wlan_hdd_free_voui(tCsrScanRequest *scan_req) qdf_mem_free(scan_req->voui); } +static int +wlan_hdd_enqueue_blocked_scan_request(struct net_device *dev, + struct cfg80211_scan_request *request, + uint8_t source) +{ + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct hdd_scan_req *blocked_scan_req = + qdf_mem_malloc(sizeof(*blocked_scan_req)); + int ret = 0; + + if (!blocked_scan_req) { + hdd_err("Failed to allocate scan_req"); + return -EINVAL; + } + + blocked_scan_req->adapter = adapter; + blocked_scan_req->scan_request = request; + blocked_scan_req->source = source; + blocked_scan_req->scan_id = 0; + + qdf_mutex_acquire(&adapter->blocked_scan_request_q_lock); + if (qdf_list_size(&adapter->blocked_scan_request_q) < + CFG_MAX_SCAN_COUNT_MAX) + qdf_list_insert_back(&adapter->blocked_scan_request_q, + &blocked_scan_req->node); + else + ret = -EINVAL; + qdf_mutex_release(&adapter->blocked_scan_request_q_lock); + + if (ret) { + hdd_err("Maximum number of block scan request reached!"); + qdf_mem_free(blocked_scan_req); + } + + return ret; +} + /* Define short name to use in cds_trigger_recovery */ #define SCAN_FAILURE CDS_SCAN_ATTEMPT_FAILURES @@ -1990,10 +2053,8 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, conn_info.connState) && (!pHddCtx->config->enable_connected_scan)) { hdd_info("enable_connected_scan is false, Aborting scan"); - if (NL_SCAN == source) - pAdapter->request = request; - else - pAdapter->vendor_request = request; + if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source)) + return -EAGAIN; schedule_work(&pAdapter->scan_block_work); return 0; } @@ -2050,10 +2111,9 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, * startup. */ hdd_err("##In DFS Master mode. Scan aborted"); - if (NL_SCAN == source) - pAdapter->request = request; - else - pAdapter->vendor_request = request; + if (wlan_hdd_enqueue_blocked_scan_request(dev, request, + source)) + return -EAGAIN; schedule_work(&pAdapter->scan_block_work); return 0; } @@ -2112,19 +2172,20 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, !pHddCtx->last_scan_reject_timestamp) { pHddCtx->last_scan_reject_session_id = curr_session_id; pHddCtx->last_scan_reject_reason = curr_reason; - pHddCtx->last_scan_reject_timestamp = - jiffies_to_msecs(jiffies) + - SCAN_REJECT_THRESHOLD_TIME; + pHddCtx->last_scan_reject_timestamp = jiffies + + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME); pHddCtx->scan_reject_cnt = 0; } else { pHddCtx->scan_reject_cnt++; if ((pHddCtx->scan_reject_cnt >= SCAN_REJECT_THRESHOLD) && - qdf_system_time_after(jiffies_to_msecs(jiffies), + qdf_system_time_after(jiffies, pHddCtx->last_scan_reject_timestamp)) { - hdd_err("scan reject threshold reached Session %d Reason %d count %d", + hdd_err("scan reject threshold reached Session %d Reason %d count %d reject timestamp %lu jiffies %lu", curr_session_id, curr_reason, - pHddCtx->scan_reject_cnt); + pHddCtx->scan_reject_cnt, + pHddCtx->last_scan_reject_timestamp, + jiffies); pHddCtx->last_scan_reject_timestamp = 0; pHddCtx->scan_reject_cnt = 0; if (pHddCtx->config->enable_fatal_event) { @@ -2145,19 +2206,16 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, } return -EBUSY; } - pHddCtx->last_scan_reject_timestamp = 0; - pHddCtx->last_scan_reject_session_id = 0xFF; - pHddCtx->last_scan_reject_reason = 0; - pHddCtx->scan_reject_cnt = 0; + + /* reinit the scan reject params */ + hdd_init_scan_reject_params(pHddCtx); /* Check whether SAP scan can be skipped or not */ if (pAdapter->device_mode == QDF_SAP_MODE && wlan_hdd_sap_skip_scan_check(pHddCtx, request)) { hdd_debug("sap scan skipped"); - if (NL_SCAN == source) - pAdapter->request = request; - else - pAdapter->vendor_request = request; + if (wlan_hdd_enqueue_blocked_scan_request(dev, request, source)) + return -EAGAIN; schedule_work(&pAdapter->scan_block_work); return 0; } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h index 518b0497bc63..04c64d34a699 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_scan.h @@ -164,6 +164,26 @@ void wlan_hdd_fill_whitelist_ie_attrs(bool *ie_whitelist, uint32_t *voui, hdd_context_t *hdd_ctx); +/** + * hdd_init_scan_reject_params() - init scan reject params + * @hdd_ctx: hdd contxt + * + * Return: None + */ +void hdd_init_scan_reject_params(hdd_context_t *hdd_ctx); + +/** + * hdd_reset_scan_reject_params() - reset scan reject params per roam stats + * @hdd_ctx: hdd contxt + * @roam_status: roam status + * @roam_result: roam result + * + * Return: None + */ +void hdd_reset_scan_reject_params(hdd_context_t *hdd_ctx, + eRoamCmdStatus roam_status, + eCsrRoamResult roam_result); + /** * wlan_hdd_cfg80211_scan_block_cb() - scan block work handler * @work: Pointer to work diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c index 70c554683f2c..8a451d8c65ea 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -4051,6 +4051,9 @@ void hdd_clear_roam_profile_ie(hdd_adapter_t *pAdapter) qdf_mem_zero(pWextState->roamProfile.Keys.KeyLength, CSR_MAX_NUM_KEY); + qdf_mem_zero(pWextState->roamProfile.Keys.KeyMaterial, + sizeof(pWextState->roamProfile.Keys.KeyMaterial)); + #ifdef FEATURE_WLAN_WAPI pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN; pAdapter->wapi_info.nWapiMode = 0; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c index f0cc82b8544e..5a7f43ce601e 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -615,6 +615,8 @@ void lim_cleanup(tpAniSirGlobal pMac) } if (pMac->lim.gpLimMlmSetKeysReq != NULL) { + qdf_mem_zero(pMac->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); qdf_mem_free(pMac->lim.gpLimMlmSetKeysReq); pMac->lim.gpLimMlmSetKeysReq = NULL; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 7e52d30711fe..5cbd33601bed 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -737,7 +737,7 @@ static void lim_print_ht_cap(tpAniSirGlobal mac_ctx, tpPESession session, * * wpa ie related checks * - * Return: true of no error, false otherwise + * Return: true if no error, false otherwise */ static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr, diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c index a0b953ec6c58..53585671f5fb 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c @@ -1184,6 +1184,11 @@ lim_process_auth_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, auth_alg = *(uint16_t *) body_ptr; pe_debug("auth_alg %d ", auth_alg); + if (frame_len < 2) { + pe_err("invalid frame len: %d", frame_len); + return; + } + /* Restore default failure timeout */ if (QDF_P2P_CLIENT_MODE == pe_session->pePersona && pe_session->defaultAuthFailureTimeout) { @@ -1229,6 +1234,11 @@ lim_process_auth_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, mac_hdr->sa, pe_session, false); goto free; } + + if (frame_len < 4) { + pe_err("invalid frame len: %d", frame_len); + goto free; + } /* Extract key ID from IV (most 2 bits of 4th byte of IV) */ key_id = (*(body_ptr + 3)) >> 6; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index 7f44b876022e..41090c31d4f8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2082,6 +2082,8 @@ lim_process_mlm_set_keys_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf; if (mac_ctx->lim.gpLimMlmSetKeysReq != NULL) { + qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } @@ -2091,6 +2093,7 @@ lim_process_mlm_set_keys_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) mlm_set_keys_req->sessionId); if (NULL == session) { pe_err("session does not exist for given sessionId"); + qdf_mem_zero(mlm_set_keys_req, sizeof(tLimMlmSetKeysReq)); qdf_mem_free(mlm_set_keys_req); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; return; diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index 6b9b5b65a882..2f6e0e97c436 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2722,6 +2722,7 @@ void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal mac_ctx, session_entry = pe_find_session_by_session_id(mac_ctx, session_id); if (session_entry == NULL) { pe_err("session does not exist for given session_id"); + qdf_mem_zero(msg->bodyptr, sizeof(tSetStaKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; lim_send_sme_set_context_rsp(mac_ctx, @@ -2747,6 +2748,7 @@ void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal mac_ctx, else mlm_set_key_cnf.key_len_nonzero = false; + qdf_mem_zero(msg->bodyptr, sizeof(tSetStaKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; @@ -2765,6 +2767,8 @@ void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal mac_ctx, * Free the buffer cached for the global * mac_ctx->lim.gpLimMlmSetKeysReq */ + qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } @@ -2808,6 +2812,7 @@ void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal mac_ctx, if (session_entry == NULL) { pe_err("session does not exist for given sessionId [%d]", session_id); + qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr, @@ -2844,6 +2849,7 @@ void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal mac_ctx, set_key_cnf.resultCode = result_status; } + qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); qdf_mem_free(msg->bodyptr); msg->bodyptr = NULL; /* Restore MLME state */ @@ -2864,6 +2870,8 @@ void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal mac_ctx, * Free the buffer cached for the * global mac_ctx->lim.gpLimMlmSetKeysReq */ + qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); mac_ctx->lim.gpLimMlmSetKeysReq = NULL; } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c index c0dd14f0921e..096bb85fd0be 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2962,6 +2962,9 @@ __lim_process_sme_set_context_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) } qdf_mem_copy(set_context_req, msg_buf, sizeof(struct sSirSmeSetContextReq)); + + qdf_mem_zero(msg_buf, sizeof(tSirSmeSetContextReq)); + sme_session_id = set_context_req->sessionId; sme_transaction_id = set_context_req->transactionId; @@ -3069,6 +3072,7 @@ __lim_process_sme_set_context_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) sme_transaction_id); } end: + qdf_mem_zero(set_context_req, sizeof(tSirSmeSetContextReq)); qdf_mem_free(set_context_req); return; } @@ -4140,6 +4144,7 @@ static void __lim_process_roam_scan_offload_req(tpAniSirGlobal mac_ctx, local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN); if (!local_ie_buf) { pe_err("Mem Alloc failed for local_ie_buf"); + qdf_mem_zero(req_buffer, sizeof(tSirRoamOffloadScanReq)); qdf_mem_free(req_buffer); return; } @@ -4167,6 +4172,7 @@ static void __lim_process_roam_scan_offload_req(tpAniSirGlobal mac_ctx, status = wma_post_ctrl_msg(mac_ctx, &wma_msg); if (eSIR_SUCCESS != status) { pe_err("Posting WMA_ROAM_SCAN_OFFLOAD_REQ failed"); + qdf_mem_zero(req_buffer, sizeof(tSirRoamOffloadScanReq)); qdf_mem_free(req_buffer); } } diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c index 6e2c75e1c347..66257ad8df9b 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_security_utils.c @@ -758,6 +758,7 @@ void lim_post_sme_set_keys_cnf(tpAniSirGlobal pMac, &pMlmSetKeysReq->peer_macaddr); /* Free up buffer allocated for mlmSetKeysReq */ + qdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)); qdf_mem_free(pMlmSetKeysReq); pMac->lim.gpLimMlmSetKeysReq = NULL; @@ -862,6 +863,8 @@ void lim_send_set_bss_key_req(tpAniSirGlobal pMac, /* Respond to SME with LIM_MLM_SETKEYS_CNF */ mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + qdf_mem_zero(pSetBssKeyParams, sizeof(tSetBssKeyParams)); + qdf_mem_free(pSetBssKeyParams); } else return; /* Continue after WMA_SET_BSSKEY_RSP... */ @@ -1034,6 +1037,7 @@ void lim_send_set_sta_key_req(tpAniSirGlobal pMac, return; /* Continue after WMA_SET_STAKEY_RSP... */ free_sta_key: + qdf_mem_zero(pSetStaKeyParams, sizeof(tSetStaKeyParams)); qdf_mem_free(pSetStaKeyParams); fail: /* Respond to SME with LIM_MLM_SETKEYS_CNF */ diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c index 70865f2fa58b..97748c81bbd8 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_session.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -839,6 +839,9 @@ void pe_delete_session(tpAniSirGlobal mac_ctx, tpPESession session) pe_delete_fils_info(session); session->valid = false; + qdf_mem_zero(session->WEPKeyMaterial, + sizeof(session->WEPKeyMaterial)); + if (session->access_policy_vendor_ie) qdf_mem_free(session->access_policy_vendor_ie); diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h index 3b0ff3aaf19c..09ba3357a7c0 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/sme_ft_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016,2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -94,6 +94,15 @@ void sme_get_ft_pre_auth_response(tHalHandle hHal, uint32_t sessionId, uint16_t *ft_ies_length); void sme_get_rici_es(tHalHandle hHal, uint32_t sessionId, uint8_t *ric_ies, uint32_t ric_ies_ip_len, uint32_t *ric_ies_length); +/** + * sme_reset_key() -Reset key information + * @mac_handle: MAC handle + * @vdev_id: vdev identifier + * + * Return: None + */ +void sme_reset_key(tHalHandle mac_handle, uint32_t vdev_id); + void sme_preauth_reassoc_intvl_timer_callback(void *context); void sme_set_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId, bool state); bool sme_get_ft_pre_auth_state(tHalHandle hHal, uint32_t sessionId); diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c index 2863ea3f99f0..6f8a4d3fe727 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_api.c @@ -9354,6 +9354,7 @@ QDF_STATUS sme_stop_roaming(tHalHandle hal, uint8_t session_id, uint8_t reason) status = wma_post_ctrl_msg(mac_ctx, &wma_msg); if (eSIR_SUCCESS != status) { sme_err("Posting WMA_ROAM_SCAN_OFFLOAD_REQ failed"); + qdf_mem_zero(req, sizeof(tSirRoamOffloadScanReq)); qdf_mem_free(req); return QDF_STATUS_E_FAULT; } @@ -18380,8 +18381,10 @@ QDF_STATUS sme_set_del_pmkid_cache(tHalHandle hal, uint8_t session_id, cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { sme_err("Not able to post message to WDA"); - if (pmk_cache) + if (pmk_cache) { + qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); qdf_mem_free(pmk_cache); + } return QDF_STATUS_E_FAILURE; } diff --git a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c index bbfcaf1b1bd6..325dad5e3929 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/common/sme_ft_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017,2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -480,6 +480,24 @@ void sme_preauth_reassoc_intvl_timer_callback(void *context) pUsrCtx->sessionId); } +void sme_reset_key(tHalHandle mac_handle, uint32_t vdev_id) +{ + tpAniSirGlobal mac = PMAC_STRUCT(mac_handle); + tCsrRoamSession *session = NULL; + + if (!mac) { + sme_err("mac is NULL"); + return; + } + + session = CSR_GET_SESSION(mac, vdev_id); + if (!session) + return; + qdf_mem_zero(&session->psk_pmk, sizeof(session->psk_pmk)); + session->pmk_len = 0; + qdf_mem_zero(&session->eseCckmInfo, sizeof(session->eseCckmInfo)); +} + /* Reset the FT context. */ void sme_ft_reset(tHalHandle hHal, uint32_t sessionId) { diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c index 4ff87dc2ee1f..15696c95ef92 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c @@ -4700,6 +4700,27 @@ static QDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac, return status; } +static void csr_reset_cfg_privacy(tpAniSirGlobal pMac) +{ + uint8_t Key0[WNI_CFG_WEP_DEFAULT_KEY_1_LEN] = {0}; + uint8_t Key1[WNI_CFG_WEP_DEFAULT_KEY_2_LEN] = {0}; + uint8_t Key2[WNI_CFG_WEP_DEFAULT_KEY_3_LEN] = {0}; + uint8_t Key3[WNI_CFG_WEP_DEFAULT_KEY_4_LEN] = {0}; + + cfg_set_int(pMac, WNI_CFG_PRIVACY_ENABLED, 0); + cfg_set_int(pMac, WNI_CFG_RSN_ENABLED, 0); + cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_1, Key0, + WNI_CFG_WEP_DEFAULT_KEY_1_LEN); + cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_2, Key1, + WNI_CFG_WEP_DEFAULT_KEY_2_LEN); + cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_3, Key2, + WNI_CFG_WEP_DEFAULT_KEY_3_LEN); + cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_4, Key3, + WNI_CFG_WEP_DEFAULT_KEY_4_LEN); + cfg_set_int(pMac, WNI_CFG_WEP_KEY_LENGTH, 0); + cfg_set_int(pMac, WNI_CFG_WEP_DEFAULT_KEYID, 0); +} + void csr_set_cfg_privacy(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, bool fPrivacy) { @@ -14500,6 +14521,8 @@ QDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac, sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED); pSession->NumPmkidCache = 0; pSession->curr_cache_idx = 0; + qdf_mem_zero(pSession->psk_pmk, sizeof(pSession->psk_pmk)); + pSession->pmk_len = 0; return QDF_STATUS_SUCCESS; } @@ -16487,8 +16510,10 @@ QDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac, status = cds_mq_post_message_by_priority( QDF_MODULE_ID_PE, &cds_msg, LOW_PRIORITY); - if (QDF_IS_STATUS_ERROR(status)) + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_zero(pMsg, msgLen); qdf_mem_free(pMsg); + } } while (0); return status; } @@ -17294,6 +17319,8 @@ void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId) /* Clean up FT related data structures */ sme_ft_close(pMac, sessionId); + sme_reset_key((tHalHandle)pMac, sessionId); + csr_reset_cfg_privacy(pMac); csr_free_connect_bss_desc(pMac, sessionId); csr_roam_free_connect_profile(&pSession->connectedProfile); csr_roam_free_connected_info(pMac, &pSession->connectedInfo); diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c index 6820c8945bc1..a3f12e474243 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_util.c @@ -3756,6 +3756,7 @@ uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId, } else { pPMK->cPMKIDs = 0; } + qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); #ifdef WLAN_FEATURE_11W /* Advertise BIP in group cipher key management only if PMF is diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma.h index 3083c1ebc967..47b6532af101 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma.h @@ -1050,6 +1050,7 @@ struct roam_synch_frame_ind { * @aid: association id * @rmfEnabled: Robust Management Frame (RMF) enabled/disabled * @key: GTK key + * @ucast_key_cipher: unicast cipher key * @uapsd_cached_val: uapsd cached value * @stats_rsp: stats response * @fw_stats_set: fw stats value @@ -1126,6 +1127,7 @@ struct wma_txrx_node { uint8_t rmfEnabled; #ifdef WLAN_FEATURE_11W wma_igtk_key_t key; + uint32_t ucast_key_cipher; #endif /* WLAN_FEATURE_11W */ uint32_t uapsd_cached_val; tAniGetPEStatsRsp *stats_rsp; diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c index 6037f0872f59..5b3e978cffc2 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2579,6 +2579,37 @@ static void wma_update_tx_send_params(struct tx_send_params *tx_param, tx_param->preamble_type); } +/** + * wma_is_rmf_mgmt_action_frame() - check RMF action frame by category + * @action_category: action frame actegory + * + * This function check the frame is robust mgmt action frame or not + * + * Return: true - if category is robust mgmt type + */ +static bool wma_is_rmf_mgmt_action_frame(uint8_t action_category) +{ + switch (action_category) { + case SIR_MAC_ACTION_SPECTRUM_MGMT: + case SIR_MAC_ACTION_QOS_MGMT: + case SIR_MAC_ACTION_DLP: + case SIR_MAC_ACTION_BLKACK: + case SIR_MAC_ACTION_RRM: + case SIR_MAC_ACTION_FAST_BSS_TRNST: + case SIR_MAC_ACTION_SA_QUERY: + case SIR_MAC_ACTION_PROT_DUAL_PUB: + case SIR_MAC_ACTION_WNM: + case SIR_MAC_ACITON_MESH: + case SIR_MAC_ACTION_MHF: + case SIR_MAC_ACTION_FST: + return true; + default: + break; + } + return false; + +} + /** * wma_tx_packet() - Sends Tx Frame to TxRx * @wma_context: wma context @@ -2620,6 +2651,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, uint8_t *pFrame = NULL; void *pPacket = NULL; uint16_t newFrmLen = 0; + uint8_t action_category = 0; + bool deauth_disassoc = false; #endif /* WLAN_FEATURE_11W */ struct wma_txrx_node *iface; tpAniSirGlobal pMac; @@ -2676,14 +2709,29 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, pFc->subType == SIR_MAC_MGMT_ACTION)) { struct ieee80211_frame *wh = (struct ieee80211_frame *)qdf_nbuf_data(tx_frame); + if (pFc->subType == SIR_MAC_MGMT_ACTION) + action_category = + *((uint8_t *)(qdf_nbuf_data(tx_frame)) + + sizeof(struct ieee80211_frame)); + else + deauth_disassoc = true; if (!IEEE80211_IS_BROADCAST(wh->i_addr1) && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { if (pFc->wep) { + uint8_t mic_len, hdr_len; + /* Allocate extra bytes for privacy header and * trailer */ - newFrmLen = frmLen + IEEE80211_CCMP_HEADERLEN + - IEEE80211_CCMP_MICLEN; + if (iface->ucast_key_cipher == + WMI_CIPHER_AES_GCM) { + hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN; + mic_len = WLAN_IEEE80211_GCMP_MICLEN; + } else { + hdr_len = IEEE80211_CCMP_HEADERLEN; + mic_len = IEEE80211_CCMP_MICLEN; + } + newFrmLen = frmLen + hdr_len + mic_len; qdf_status = cds_packet_alloc((uint16_t) newFrmLen, (void **)&pFrame, @@ -2706,7 +2754,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, qdf_mem_set(pFrame, newFrmLen, 0); qdf_mem_copy(pFrame, wh, sizeof(*wh)); qdf_mem_copy(pFrame + sizeof(*wh) + - IEEE80211_CCMP_HEADERLEN, + hdr_len, pData + sizeof(*wh), frmLen - sizeof(*wh)); @@ -2717,7 +2765,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, pFc = (tpSirMacFrameCtl) (qdf_nbuf_data(tx_frame)); } - } else { + } else if (deauth_disassoc || + wma_is_rmf_mgmt_action_frame(action_category)) { /* Allocate extra bytes for MMIE */ newFrmLen = frmLen + IEEE80211_MMIE_LEN; qdf_status = cds_packet_alloc((uint16_t) newFrmLen, diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c index 3b2da0866420..56d4542cead2 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1881,6 +1881,17 @@ wma_remove_peer_by_reference(ol_txrx_pdev_handle pdev, return status; } +#ifdef WLAN_FEATURE_11W +static void wma_clear_iface_key(struct wma_txrx_node *iface) +{ + qdf_mem_zero(&iface->key, sizeof(iface->key)); +} +#else +static void wma_clear_iface_key(struct wma_txrx_node *iface) +{ +} +#endif + /** * wma_vdev_stop_resp_handler() - vdev stop response handler * @handle: wma handle @@ -1932,6 +1943,8 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, resp_event->vdev_id); } + /* Clear key information */ + wma_clear_iface_key(iface); wma_release_wakelock(&iface->vdev_stop_wakelock); req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c index 5a71b110673b..fb546c0b22a4 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -8304,8 +8304,10 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) case SIR_HAL_SET_DEL_PMKID_CACHE: wma_set_del_pmkid_cache(wma_handle, (wmi_pmk_cache *) msg->bodyptr, msg->reserved); - if (msg->bodyptr) + if (msg->bodyptr) { + qdf_mem_zero(msg->bodyptr, sizeof(wmi_pmk_cache)); qdf_mem_free(msg->bodyptr); + } break; case SIR_HAL_HLP_IE_INFO: wma_roam_scan_send_hlp(wma_handle, diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c index b7e4ed4ce78f..5e61e621384a 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1714,10 +1714,11 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, params.key_len = key_params->key_len; #ifdef WLAN_FEATURE_11W + iface = &wma_handle->interfaces[key_params->vdev_id]; + if ((key_params->key_type == eSIR_ED_AES_128_CMAC) || (key_params->key_type == eSIR_ED_AES_GMAC_128) || (key_params->key_type == eSIR_ED_AES_GMAC_256)) { - iface = &wma_handle->interfaces[key_params->vdev_id]; if (iface) { iface->key.key_length = key_params->key_len; iface->key.key_cipher = params.key_cipher; @@ -1731,6 +1732,9 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, CMAC_IPN_LEN); } } + + if (key_params->unicast && iface) + iface->ucast_key_cipher = params.key_cipher; #endif /* WLAN_FEATURE_11W */ WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d", @@ -1754,6 +1758,7 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, if (iface) iface->is_waiting_for_key = false; + qdf_mem_zero(¶ms, sizeof(struct set_key_params)); return status; } @@ -1880,6 +1885,8 @@ void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */ key_info->status = QDF_STATUS_SUCCESS; + qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params)); + out: wma_send_msg_high_priority(wma_handle, WMA_SET_BSSKEY_RSP, (void *)key_info, 0); @@ -2170,6 +2177,7 @@ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info) key_params.key_len = key_info->key[i].keyLength; status = wma_setup_install_key_cmd(wma_handle, &key_params, opmode); + qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params)); if (status == QDF_STATUS_E_NOMEM) { WMA_LOGE("%s:Failed to setup install key buf", __func__); @@ -3357,6 +3365,7 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle, { uint8_t *orig_hdr; uint8_t *ccmp; + uint8_t mic_len, hdr_len; if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) { if (IEEE80211_IS_BROADCAST(wh->i_addr1) || @@ -3383,15 +3392,22 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle, return -EINVAL; } + if (iface->ucast_key_cipher == WMI_CIPHER_AES_GCM) { + hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN; + mic_len = WLAN_IEEE80211_GCMP_MICLEN; + } else { + hdr_len = IEEE80211_CCMP_HEADERLEN; + mic_len = IEEE80211_CCMP_MICLEN; + } /* Strip privacy headers (and trailer) * for a received frame */ qdf_mem_move(orig_hdr + - IEEE80211_CCMP_HEADERLEN, wh, + hdr_len, wh, sizeof(*wh)); qdf_nbuf_pull_head(wbuf, - IEEE80211_CCMP_HEADERLEN); - qdf_nbuf_trim_tail(wbuf, IEEE80211_CCMP_MICLEN); + hdr_len); + qdf_nbuf_trim_tail(wbuf, mic_len); /* * CCMP header has been pulled off * reinitialize the start pointer of mac header diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c index c39c80c851db..231a36d31c71 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c @@ -988,11 +988,12 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle, scan_cmd_fp, params); + qdf_mem_zero(params, sizeof(struct roam_offload_scan_params)); + qdf_mem_free(params); if (QDF_IS_STATUS_ERROR(status)) return status; WMA_LOGD("%s: WMA --> WMI_ROAM_SCAN_MODE", __func__); - qdf_mem_free(params); return status; } @@ -2052,6 +2053,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, if (NULL == pMac) { WMA_LOGE("%s: pMac is NULL", __func__); + qdf_mem_zero(roam_req, sizeof(tSirRoamOffloadScanReq)); qdf_mem_free(roam_req); return QDF_STATUS_E_FAILURE; } @@ -2060,6 +2062,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, /* roam scan offload is not enabled in firmware. * Cannot initialize it in the middle of connection. */ + qdf_mem_zero(roam_req, sizeof(tSirRoamOffloadScanReq)); qdf_mem_free(roam_req); return QDF_STATUS_E_PERM; } @@ -2422,6 +2425,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, default: break; } + qdf_mem_zero(roam_req, sizeof(tSirRoamOffloadScanReq)); qdf_mem_free(roam_req); return qdf_status; }