diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-08-02 14:52:49 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-08-02 14:52:49 +0000 |
commit | ff599ce3890e4d99d621ef783361b7b01422d32b (patch) | |
tree | 7275ebd43b63e2683f188722e00c12aed496dbc9 | |
parent | d14e4d704776cca45d5675c3a86d356370760d1c (diff) | |
parent | 0f5a1fb2980af0eb9a11b57cccfd5fd3a86f1d66 (diff) | |
download | qcom-msm8x09-v3.10-ff599ce3890e4d99d621ef783361b7b01422d32b.tar.gz |
Snap for 4927517 from 0f5a1fb2980af0eb9a11b57cccfd5fd3a86f1d66 to nyc-iot-release
Change-Id: I9e6d90d991d91d5b2715e92c9c10f53b7dad1e01
20 files changed, 2799 insertions, 866 deletions
diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c index 8742c1ae61e..c3fe8071ec7 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -642,14 +642,37 @@ htt_t2h_tx_ppdu_log_print( { int i; int record_size; + int calculated_record_size; int num_records; - record_size = - sizeof(*record) + - hdr->mpdu_bytes_array_len * sizeof(u_int16_t) + - hdr->mpdu_msdus_array_len * sizeof(u_int8_t) + - hdr->msdu_bytes_array_len * sizeof(u_int16_t); + record_size = sizeof(*record); + calculated_record_size = record_size + + hdr->mpdu_bytes_array_len * sizeof(uint16_t); + if (calculated_record_size < record_size) { + adf_os_print("Overflow due to record and hdr->mpdu_bytes_array_len %u\n", + hdr->mpdu_bytes_array_len); + return; + } + record_size = calculated_record_size; + calculated_record_size += hdr->mpdu_msdus_array_len * sizeof(uint8_t); + if (calculated_record_size < record_size) { + adf_os_print("Overflow due to hdr->mpdu_msdus_array_len %u\n", + hdr->mpdu_msdus_array_len); + return; + } + record_size = calculated_record_size; + calculated_record_size += hdr->msdu_bytes_array_len * sizeof(uint16_t); + if (calculated_record_size < record_size) { + adf_os_print("Overflow due to hdr->msdu_bytes_array_len %u\n", + hdr->msdu_bytes_array_len); + return; + } + record_size = calculated_record_size; num_records = (length - sizeof(*hdr)) / record_size; + if (num_records < 0) { + adf_os_print("Underflow due to length %d\n", length); + return; + } adf_os_print("Tx PPDU log elements:\n"); for (i = 0; i < num_records; i++) { @@ -681,6 +704,8 @@ htt_t2h_tx_ppdu_log_print( #define BUF_SIZE 80 char buf[BUF_SIZE]; u_int8_t *p8; + u_int8_t *calculated_p8; + time_enqueue_us = HTT_T2H_STATS_TX_PPDU_TIME_TO_MICROSEC( record->timestamp_enqueue, hdr->microsec_per_tick); time_completion_us = HTT_T2H_STATS_TX_PPDU_TIME_TO_MICROSEC( @@ -742,19 +767,36 @@ htt_t2h_tx_ppdu_log_print( } /* skip past the regular message fields to reach the tail area */ p8 = (u_int8_t *) record; - p8 += sizeof(struct ol_fw_tx_dbg_ppdu_base); + calculated_p8 = p8 + sizeof(struct ol_fw_tx_dbg_ppdu_base); + if (calculated_p8 < p8) { + adf_os_print("Overflow due to record %p\n", p8); + continue; + } + p8 = calculated_p8; if (hdr->mpdu_bytes_array_len) { htt_make_u16_list_str( (u_int32_t *) p8, buf, BUF_SIZE, hdr->mpdu_bytes_array_len); adf_os_print(" MPDU bytes: %s\n", buf); } - p8 += hdr->mpdu_bytes_array_len * sizeof(u_int16_t); + calculated_p8 += hdr->mpdu_bytes_array_len * sizeof(u_int16_t); + if (calculated_p8 < p8) { + adf_os_print("Overflow due to hdr->mpdu_bytes_array_len %u\n", + hdr->mpdu_bytes_array_len); + continue; + } + p8 = calculated_p8; if (hdr->mpdu_msdus_array_len) { htt_make_u8_list_str( (u_int32_t *) p8, buf, BUF_SIZE, hdr->mpdu_msdus_array_len); adf_os_print(" MPDU MSDUs: %s\n", buf); } - p8 += hdr->mpdu_msdus_array_len * sizeof(u_int8_t); + calculated_p8 += hdr->mpdu_msdus_array_len * sizeof(u_int8_t); + if (calculated_p8 < p8) { + adf_os_print("Overflow due to hdr->mpdu_msdus_array_len %u\n", + hdr->mpdu_msdus_array_len); + continue; + } + p8 = calculated_p8; if (hdr->msdu_bytes_array_len) { htt_make_u16_list_str( (u_int32_t *) p8, buf, BUF_SIZE, hdr->msdu_bytes_array_len); diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c index a44a4b065b7..3a66b13dac0 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -1412,6 +1412,13 @@ ol_rx_in_order_indication_handler( int status; adf_nbuf_t head_msdu, tail_msdu = NULL; + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: invalid tid, %u\n", __FUNCTION__, tid); + WARN_ON(1); + return; + } + if (pdev) { peer = ol_txrx_peer_find_by_id(pdev, peer_id); if (VOS_MONITOR_MODE == vos_get_conparam()) diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c index 0e9928a332b..1fc62d3ab1b 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c @@ -489,6 +489,12 @@ static void ol_rx_reorder_detect_hole(struct ol_txrx_peer_t *peer, { uint32_t win_sz_mask, next_rel_idx, hole_size; + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: invalid tid, %u\n", __func__, tid); + return; + } + if (peer->tids_next_rel_idx[tid] == INVALID_REORDER_INDEX) return; diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c index bc6120b6749..1397f1121fd 100644 --- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -805,6 +805,12 @@ ol_tx_desc_update_group_credit(ol_txrx_pdev_handle pdev, u_int16_t tx_desc_id, uint16_t vdev_id_mask; struct ol_tx_desc_t *tx_desc; + if (tx_desc_id >= pdev->tx_desc.pool_size) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid desc id %d", __func__, tx_desc_id); + return; + } + tx_desc = ol_tx_desc_find(pdev, tx_desc_id); for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) { diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h index ebc56c1afef..96fd0cd13c1 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h @@ -1440,7 +1440,6 @@ struct hdd_adapter_s struct hdd_netif_queue_history queue_oper_history[WLAN_HDD_MAX_HISTORY_ENTRY]; struct hdd_netif_queue_stats queue_oper_stats[WLAN_REASON_TYPE_MAX]; - struct power_stats_response *chip_power_stats; /* random address management for management action frames */ spinlock_t random_mac_lock; @@ -1921,11 +1920,6 @@ struct hdd_context_s /* debugfs entry */ struct dentry *debugfs_phy; -#ifdef WLAN_POWER_DEBUGFS - /* mutex lock to block concurrent access */ - struct mutex power_stats_lock; -#endif - /* Use below lock to protect access to isSchedScanUpdatePending * since it will be accessed in two different contexts. */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h index 6a47ede7e6e..8153b356b6c 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h @@ -346,6 +346,10 @@ typedef struct ccp_freq_chan_map_s{ v_U32_t chan; }hdd_freq_chan_map_t; +struct temperature_info { + int temperature; +}; + #define wlan_hdd_get_wps_ie_ptr(ie, ie_len) \ wlan_hdd_get_vendor_oui_ie_ptr(WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE, ie, ie_len) @@ -427,7 +431,6 @@ extern void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len); extern VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, tSirMacAddr macAddress); void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter); -void hdd_GetClassA_statisticsCB(void *pStats, void *pContext); void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext); VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter); @@ -479,7 +482,7 @@ int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal, int process_wma_set_command_twoargs(int sessid, int paramid, int sval, int ssecval, int vpdev); -void hdd_GetTemperatureCB(int temperature, void *pContext); -VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, +void hdd_GetTemperatureCB(int temperature, void *cookie); +VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *adapter_ptr, union iwreq_data *wrqu, char *extra); #endif // __WEXT_IW_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c index 05df4f3c362..85e07fcda47 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -14077,6 +14077,10 @@ fail: return -EINVAL; } +struct peer_txrx_rate_priv { + struct sir_peer_info_ext peer_info_ext; +}; + /** * hdd_get_peer_txrx_rate_cb() - get station's txrx rate callback * @peer_info: pointer of peer information @@ -14086,84 +14090,38 @@ fail: * adapter */ static void hdd_get_peer_txrx_rate_cb(struct sir_peer_info_ext_resp *peer_info, - void *context) + void *context) { - struct statsContext *get_txrx_rate_context; - struct sir_peer_info_ext *txrx_rate = NULL; - hdd_adapter_t *adapter; - uint8_t staid; - - if ((NULL == peer_info) || (NULL == context)) { + struct hdd_request *request; + struct peer_txrx_rate_priv *priv; + if (NULL == peer_info) { hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Bad param, peer_info [%pK] context [%pK]", - __func__, peer_info, context); - return; - } - - spin_lock(&hdd_context_lock); - /* - * there is a race condition that exists between this callback - * function and the caller since the caller could time out either - * before or while this code is executing. we use a spinlock to - * serialize these actions - */ - get_txrx_rate_context = context; - if (PEER_INFO_CONTEXT_MAGIC != - get_txrx_rate_context->magic) { - - /* - * the caller presumably timed out so there is nothing - * we can do - */ - spin_unlock(&hdd_context_lock); - hddLog(VOS_TRACE_LEVEL_WARN, - "%s: Invalid context, magic [%08x]", - __func__, - get_txrx_rate_context->magic); + "%s: Bad param, peer_info [%pK]", + __func__, peer_info); return; } if (!peer_info->count) { - spin_unlock(&hdd_context_lock); hddLog(VOS_TRACE_LEVEL_ERROR, - FL("Fail to get remote peer info")); + FL("Fail to get remote peer info")); return; } - adapter = get_txrx_rate_context->pAdapter; - txrx_rate = peer_info->info; - if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(adapter, - (v_MACADDR_t *)txrx_rate->peer_macaddr, - &staid)) { - spin_unlock(&hdd_context_lock); - hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Station MAC address does not matching", - __func__); + request = hdd_request_get(context); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__); return; } - adapter->aStaInfo[staid].tx_rate = txrx_rate->tx_rate; - adapter->aStaInfo[staid].rx_rate = txrx_rate->rx_rate; - hddLog(VOS_TRACE_LEVEL_INFO, "%s txrate %x rxrate %x\n", - __func__, - adapter->aStaInfo[staid].tx_rate, - adapter->aStaInfo[staid].rx_rate); - - get_txrx_rate_context->magic = 0; - - /* notify the caller */ - complete(&get_txrx_rate_context->completion); + priv = hdd_request_priv(request); - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + vos_mem_copy(&priv->peer_info_ext, + peer_info->info, + sizeof(peer_info->info[0])); - if (txrx_rate) - hddLog(VOS_TRACE_LEVEL_INFO, "%s %pM tx rate %u rx rate %u", - __func__, - txrx_rate->peer_macaddr, - txrx_rate->tx_rate, - txrx_rate->rx_rate); + hdd_request_complete(request); + hdd_request_put(request); } /** @@ -14171,17 +14129,25 @@ static void hdd_get_peer_txrx_rate_cb(struct sir_peer_info_ext_resp *peer_info, * @adapter: hostapd interface * @macaddress: mac address of requested peer * - * This function call sme_get_peer_info_ext to get txrx rate + * This function call sme_get_peer_info_ext to get StaInfo[staid] txrx rate * * Return: 0 on success, otherwise error value */ static int wlan_hdd_get_txrx_rate(hdd_adapter_t *adapter, - v_MACADDR_t macaddress) + v_MACADDR_t macaddress) { eHalStatus hstatus; int ret; - struct statsContext context; + uint8_t staid; + void *cookie; struct sir_peer_info_ext_req txrx_rate_req; + struct hdd_request *request; + struct peer_txrx_rate_priv *priv; + v_MACADDR_t *peer_macaddr; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; if (NULL == adapter) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", @@ -14189,17 +14155,23 @@ static int wlan_hdd_get_txrx_rate(hdd_adapter_t *adapter, return -EFAULT; } - init_completion(&context.completion); - context.magic = PEER_INFO_CONTEXT_MAGIC; - context.pAdapter = adapter; + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Request allocation failure", + __func__); + return -ENOMEM; + } + + cookie = hdd_request_cookie(request); + priv = hdd_request_priv(request); vos_mem_copy(&(txrx_rate_req.peer_macaddr), &macaddress, - VOS_MAC_ADDR_SIZE); + VOS_MAC_ADDR_SIZE); txrx_rate_req.sessionid = adapter->sessionId; txrx_rate_req.reset_after_request = 0; hstatus = sme_get_peer_info_ext(WLAN_HDD_GET_HAL_CTX(adapter), &txrx_rate_req, - &context, + cookie, hdd_get_peer_txrx_rate_cb); if (eHAL_STATUS_SUCCESS != hstatus) { hddLog(VOS_TRACE_LEVEL_ERROR, @@ -14207,32 +14179,41 @@ static int wlan_hdd_get_txrx_rate(hdd_adapter_t *adapter, __func__); ret = -EFAULT; } else { - if (!wait_for_completion_timeout(&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS))) { + ret = hdd_request_wait_for_response(request); + if (ret) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME timed out while retrieving txrx_rate", __func__); ret = -EFAULT; } else { - ret = 0; + peer_macaddr = + (v_MACADDR_t *)priv->peer_info_ext.peer_macaddr; + + if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(adapter, + peer_macaddr, + &staid)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Station MAC address does not matching")); + ret = -EFAULT; + } else { + adapter->aStaInfo[staid].tx_rate = + priv->peer_info_ext.tx_rate; + adapter->aStaInfo[staid].rx_rate = + priv->peer_info_ext.rx_rate; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s %pM tx rate %u rx rate %u", + __func__, + peer_macaddr, + adapter->aStaInfo[staid].tx_rate, + adapter->aStaInfo[staid].rx_rate); + ret = 0; + } } } - /* - * either we never sent a request, we sent a request and received a - * response or we sent a request and timed out. if we never sent a - * request or if we sent a request and got a response, we want to - * clear the magic out of paranoia. if we timed out there is a - * race condition such that the callback function could be - * executing at the same time we are. of primary concern is if the - * callback function had already verified the "magic" but had not - * yet set the completion variable when a timeout occurred. we - * serialize these activities by invalidating the magic while - * holding a shared spinlock which will cause us to block if the - * callback is currently executing - */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + + hdd_request_put(request); + return ret; } @@ -24496,6 +24477,12 @@ static int wlan_hdd_cfg80211_set_privacy_ibss( if (NULL != ie) { pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA; + if (ie[1] < DOT11F_IE_WPA_MIN_LEN || + ie[1] > DOT11F_IE_WPA_MAX_LEN) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid ie len:%d"), + ie[1]); + return -EINVAL; + } // Unpack the WPA IE //Skip past the EID byte and length byte - and four byte WiFi OUI dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c index b4a7205bf33..9fde00ac2c7 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c @@ -31,6 +31,7 @@ #include <vos_sched.h> #include "wlan_hdd_debugfs.h" #include "wlan_hdd_debugfs_ocb.h" +#include "wlan_hdd_request_manager.h" #define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8 #define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512 @@ -599,78 +600,58 @@ int wlan_hdd_debugfs_open(struct inode *inode, struct file *file) } #ifdef WLAN_POWER_DEBUGFS -/** - * hdd_power_debugstats_cb() - callback routine for Power stats debugs - * @response: Pointer to Power stats response - * @context: Pointer to statsContext - * - * Return: None - */ -static void hdd_power_debugstats_cb(struct power_stats_response *response, - void *context) +struct power_stats_priv { + struct power_stats_response power_stats; +}; + +static void hdd_power_debugstats_dealloc(void *priv) { - struct statsContext *stats_context; - struct power_stats_response *power_stats; - hdd_adapter_t *adapter; - uint32_t power_stats_len; - uint32_t stats_registers_len; + struct power_stats_priv *stats = priv; - ENTER(); - if (NULL == context) { - hddLog(LOGE, FL("context is NULL")); - return; + if (stats->power_stats.debug_registers) { + vos_mem_free(stats->power_stats.debug_registers); + stats->power_stats.debug_registers = NULL; } +} + +static void hdd_power_debugstats_cb(struct power_stats_response *response, + void *context) +{ + struct hdd_request *request; + struct power_stats_priv *priv; + uint32_t *debug_registers; + uint32_t debug_registers_len; - stats_context = (struct statsContext *)context; + ENTER(); - spin_lock(&hdd_context_lock); - adapter = stats_context->pAdapter; - if ((POWER_STATS_MAGIC != stats_context->magic) || - (NULL == adapter) || - (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) { - spin_unlock(&hdd_context_lock); - hddLog(LOGE, FL("Invalid context, adapter [%pK] magic [%08x]"), - adapter, stats_context->magic); + request = hdd_request_get(context); + if (!request) { + hddLog(LOGE, FL("Obsolete request")); return; } - /* Invalidate the Stats context magic */ - stats_context->magic = 0; - - stats_registers_len = (sizeof(response->debug_registers[0]) * - response->num_debug_register); - power_stats_len = stats_registers_len + sizeof(*power_stats); - adapter->chip_power_stats = vos_mem_malloc(power_stats_len); - if (!adapter->chip_power_stats) { - hddLog(LOGE, FL("Power stats memory alloc fails!")); - goto exit_stats_cb; + priv = hdd_request_priv(request); + + /* copy fixed-sized data */ + priv->power_stats = *response; + + /* copy variable-size data */ + if (response->num_debug_register) { + debug_registers_len = (sizeof(response->debug_registers[0]) * + response->num_debug_register); + debug_registers = vos_mem_malloc(debug_registers_len); + priv->power_stats.debug_registers = debug_registers; + if (debug_registers) { + vos_mem_copy(debug_registers, + response->debug_registers, + debug_registers_len); + } else { + hddLog(LOGE, FL("Power stats memory alloc fails!")); + priv->power_stats.num_debug_register = 0; + } } - - power_stats = adapter->chip_power_stats; - vos_mem_zero(power_stats, power_stats_len); - - power_stats->cumulative_sleep_time_ms - = response->cumulative_sleep_time_ms; - power_stats->cumulative_total_on_time_ms - = response->cumulative_total_on_time_ms; - power_stats->deep_sleep_enter_counter - = response->deep_sleep_enter_counter; - power_stats->last_deep_sleep_enter_tstamp_ms - = response->last_deep_sleep_enter_tstamp_ms; - power_stats->debug_register_fmt - = response->debug_register_fmt; - power_stats->num_debug_register - = response->num_debug_register; - - power_stats->debug_registers = (uint32_t *)(power_stats + 1); - - vos_mem_copy(power_stats->debug_registers, - response->debug_registers, - stats_registers_len); - -exit_stats_cb: - complete(&stats_context->completion); - spin_unlock(&hdd_context_lock); + hdd_request_complete(request); + hdd_request_put(request); EXIT(); } @@ -689,12 +670,20 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file, { hdd_adapter_t *adapter; hdd_context_t *hdd_ctx; - struct statsContext context; + VOS_STATUS status; struct power_stats_response *chip_power_stats; ssize_t ret_cnt = 0; - int rc = 0, j; + int j; unsigned int len = 0; - char *power_debugfs_buf; + char *power_debugfs_buf = NULL; + void *cookie; + struct hdd_request *request; + struct power_stats_priv *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_POWER_STATS, + .dealloc = hdd_power_debugstats_dealloc, + }; ENTER(); adapter = (hdd_adapter_t *)file->private_data; @@ -709,52 +698,38 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file, if (0 != ret_cnt) return ret_cnt; - mutex_lock(&hdd_ctx->power_stats_lock); - - if (adapter->chip_power_stats) - vos_mem_free(adapter->chip_power_stats); - - adapter->chip_power_stats = NULL; - context.pAdapter = adapter; - context.magic = POWER_STATS_MAGIC; - - init_completion(&context.completion); + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(LOGE, FL("Request allocation failure")); + return -ENOMEM; + } + vos_mem_zero(hdd_request_priv(request), sizeof(*priv)); + cookie = hdd_request_cookie(request); - if (eHAL_STATUS_SUCCESS != - sme_power_debug_stats_req(hdd_ctx->hHal, - hdd_power_debugstats_cb, - &context)) { + status = sme_power_debug_stats_req(hdd_ctx->hHal, + hdd_power_debugstats_cb, + cookie); + if (!VOS_IS_STATUS_SUCCESS(status)) { hddLog(LOGE, FL("chip power stats request failed")); ret_cnt = -EINVAL; - goto out; + goto cleanup; } - rc = wait_for_completion_timeout(&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_POWER_STATS)); - if (!rc) { + ret_cnt = hdd_request_wait_for_response(request); + if (ret_cnt) { hddLog(LOGE, FL("Target response timed out Power stats")); - /* Invalidate the Stats context magic */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); ret_cnt = -ETIMEDOUT; - goto out; + goto cleanup; } - chip_power_stats = adapter->chip_power_stats; - if (!chip_power_stats) { - hddLog(LOGE, FL("Power stats retrieval fails!")); - ret_cnt = -EINVAL; - goto out; - } + priv = hdd_request_priv(request); + chip_power_stats = &priv->power_stats; power_debugfs_buf = vos_mem_malloc(POWER_DEBUGFS_BUFFER_MAX_LEN); if (!power_debugfs_buf) { hddLog(LOGE, FL("Power stats buffer alloc fails!")); - vos_mem_free(chip_power_stats); - adapter->chip_power_stats = NULL; ret_cnt = -EINVAL; - goto out; + goto cleanup; } len += scnprintf(power_debugfs_buf, POWER_DEBUGFS_BUFFER_MAX_LEN, @@ -782,15 +757,14 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file, j = chip_power_stats->num_debug_register; } - vos_mem_free(chip_power_stats); - adapter->chip_power_stats = NULL; - ret_cnt = simple_read_from_buffer(buf, count, pos, power_debugfs_buf, len); - vos_mem_free(power_debugfs_buf); +cleanup: + if (power_debugfs_buf) + vos_mem_free(power_debugfs_buf); + + hdd_request_put(request); -out: - mutex_unlock(&hdd_ctx->power_stats_lock); return ret_cnt; } @@ -893,8 +867,6 @@ static VOS_STATUS wlan_hdd_init_power_stats_debugfs(hdd_adapter_t *adapter, &fops_powerdebugs)) return VOS_STATUS_E_FAILURE; - mutex_init(&hdd_ctx->power_stats_lock); - return VOS_STATUS_SUCCESS; } @@ -905,7 +877,6 @@ static VOS_STATUS wlan_hdd_init_power_stats_debugfs(hdd_adapter_t *adapter, */ static void wlan_hdd_deinit_power_stats_debugfs(hdd_context_t *hdd_ctx) { - mutex_destroy(&hdd_ctx->power_stats_lock); } #else static VOS_STATUS wlan_hdd_init_power_stats_debugfs(hdd_adapter_t *adapter, diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c index f925c244351..f38eb00b85f 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c @@ -6053,58 +6053,6 @@ static int iw_get_ap_freq(struct net_device *dev, return ret; } -/** - * __iw_get_mode() - get mode - * @dev - Pointer to the net device. - * @info - Pointer to the iw_request_info. - * @wrqu - Pointer to the iwreq_data. - * @extra - Pointer to the data. - * - * Return: 0 for success, non zero for failure. - */ -static int __iw_get_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - hdd_adapter_t *adapter; - hdd_context_t *hdd_ctx; - int ret; - - adapter = WLAN_HDD_GET_PRIV_PTR(dev); - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) - return ret; - - wrqu->mode = IW_MODE_MASTER; - - return ret; -} - -/** - * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR. - * @dev - Pointer to the net device. - * @info - Pointer to the iw_request_info. - * @wrqu - Pointer to the iwreq_data. - * @extra - Pointer to the data. - * - * Return: 0 for success, non zero for failure. - */ -static int iw_get_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - - vos_ssr_protect(__func__); - ret = __iw_get_mode(dev, info, wrqu, extra); - vos_ssr_unprotect(__func__); - - return ret; -} - - static int __iw_softap_stopbss(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, @@ -6837,7 +6785,7 @@ static const iw_handler hostapd_handler[] = (iw_handler) NULL, /* SIOCSIWFREQ */ (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */ (iw_handler) NULL, /* SIOCSIWMODE */ - (iw_handler) iw_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ (iw_handler) NULL, /* SIOCGIWSENS */ (iw_handler) NULL, /* SIOCSIWRANGE */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c index 5a4160e0105..3062bffbd3c 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c @@ -5070,7 +5070,7 @@ static int hdd_driver_rxfilter_comand_handler(uint8_t *command, ret = kstrtou8(value, 10, &type); if (ret < 0) { hddLog(LOGE, - FL("kstrtou8 failed invalid input value %d"), type); + FL("kstrtou8 failed invalid input value")); return -EINVAL; } diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c index d511f9b097b..8de1fd9cf7b 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1013,18 +1013,10 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy, tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE]); /* Get the ndl chan array and the ndl active state array. */ - if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY]) { - hddLog(LOGE, FL("NDL_CHANNEL_ARRAY is not present")); - return -EINVAL; - } ndl_chan_list = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY]; ndl_chan_list_len = (ndl_chan_list ? nla_len(ndl_chan_list) : 0); - if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY]) { - hddLog(LOGE, FL("NDL_ACTIVE_STATE_ARRAY is not present")); - return -EINVAL; - } ndl_active_state_list = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY]; ndl_active_state_list_len = (ndl_active_state_list ? diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c index dafdaf5eced..da01f76cd84 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c @@ -1174,12 +1174,18 @@ static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter, return -EINVAL; } - if (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) { + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if ((pRemainChanCtx) && + (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request)) { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); if (eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame( WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0)) hddLog(LOGE, FL("sme_RegisterMgmtFrame returned failure")); + } else { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); } } else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c index 877c23e9627..e66b9e73298 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c @@ -2003,188 +2003,6 @@ static int iw_get_name(struct net_device *dev, return ret; } - -/** - * __iw_set_mode() - SIOCSIWMODE ioctl handler - * @dev: device upon which the ioctl was received - * @info: ioctl request information - * @wrqu: ioctl request data - * @extra: ioctl extra data - * - * Return: 0 on success, non-zero on error - */ -static int __iw_set_mode(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - hdd_wext_state_t *pWextState; - hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); - tCsrRoamProfile *pRoamProfile; - eCsrRoamBssType LastBSSType; - eMib_dot11DesiredBssType connectedBssType; - hdd_config_t *pConfig; - struct wireless_dev *wdev; - hdd_context_t *hdd_ctx; - int ret; - - ENTER(); - - hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); - ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) - return ret; - - pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); - wdev = dev->ieee80211_ptr; - pRoamProfile = &pWextState->roamProfile; - LastBSSType = pRoamProfile->BSSType; - - hddLog(LOG1, "%s Old Bss type = %d", __func__, LastBSSType); - - switch (wrqu->mode) - { - case IW_MODE_ADHOC: - hddLog(LOG1, "%s Setting AP Mode as IW_MODE_ADHOC", __func__); - pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS; - // Set the phymode correctly for IBSS. - pConfig = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; - pWextState->roamProfile.phyMode = hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode); - pAdapter->device_mode = WLAN_HDD_IBSS; - wdev->iftype = NL80211_IFTYPE_ADHOC; - break; - case IW_MODE_INFRA: - hddLog(LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __func__); - pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; - wdev->iftype = NL80211_IFTYPE_STATION; - break; - case IW_MODE_AUTO: - hddLog(LOG1, "%s Setting AP Mode as IW_MODE_AUTO", __func__); - pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY; - break; - default: - hddLog(LOGE, "%s Unknown AP Mode value %d ", __func__, wrqu->mode); - return -EOPNOTSUPP; - } - - if ( LastBSSType != pRoamProfile->BSSType ) - { - //the BSS mode changed - // We need to issue disconnect if connected or in IBSS disconnect state - if ( hdd_connGetConnectedBssType( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) || - ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) ) - { - VOS_STATUS vosStatus; - // need to issue a disconnect to CSR. - INIT_COMPLETION(pAdapter->disconnect_comp_var); - vosStatus = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), - pAdapter->sessionId, - eCSR_DISCONNECT_REASON_IBSS_LEAVE ); - if(VOS_STATUS_SUCCESS == vosStatus) - { - unsigned long rc; - rc = wait_for_completion_timeout( - &pAdapter->disconnect_comp_var, - msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); - if (!rc) - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("failed wait on disconnect_comp_var")); - } - } - } - - EXIT(); - return 0; -} - -/** - * iw_set_mode() - SSR wrapper for __iw_set_mode() - * @dev: pointer to net_device - * @info: pointer to iw_request_info - * @wrqu: pointer to iwreq_data - * @extra: pointer to extra ioctl payload - * - * Return: 0 on success, error number otherwise - */ -static int iw_set_mode(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - - vos_ssr_protect(__func__); - ret = __iw_set_mode(dev, info, wrqu, extra); - vos_ssr_unprotect(__func__); - - return ret; -} - -/** - * __iw_get_mode() - SIOCGIWMODE ioctl handler - * @dev: device upon which the ioctl was received - * @info: ioctl request information - * @wrqu: ioctl request data - * @extra: ioctl extra data - * - * Return: 0 on success, non-zero on error - */ -static int -__iw_get_mode(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - hdd_wext_state_t *pWextState; - hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); - hdd_context_t *hdd_ctx; - int ret; - - ENTER(); - - hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); - ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) - return ret; - - pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); - - switch (pWextState->roamProfile.BSSType) { - case eCSR_BSS_TYPE_INFRASTRUCTURE: - hddLog(LOG1, FL("returns IW_MODE_INFRA")); - wrqu->mode = IW_MODE_INFRA; - break; - case eCSR_BSS_TYPE_IBSS: - case eCSR_BSS_TYPE_START_IBSS: - hddLog(LOG1, FL("returns IW_MODE_ADHOC")); - wrqu->mode = IW_MODE_ADHOC; - break; - case eCSR_BSS_TYPE_ANY: - default: - hddLog(LOG1, FL("returns IW_MODE_AUTO")); - wrqu->mode = IW_MODE_AUTO; - break; - } - - EXIT(); - return 0; -} - -/** - * iw_get_mode() - SSR wrapper for __iw_get_mode() - * @dev: pointer to net_device - * @info: pointer to iw_request_info - * @wrqu: pointer to iwreq_data - * @extra: pointer to extra ioctl payload - * - * Return: 0 on success, error number otherwise - */ -static int iw_get_mode(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - - vos_ssr_protect(__func__); - ret = __iw_get_mode(dev, info, wrqu, extra); - vos_ssr_unprotect(__func__); - - return ret; -} - /** * __iw_set_freq() - SIOCSIWFREQ ioctl handler * @dev: device upon which the ioctl was received @@ -3644,55 +3462,6 @@ static void iw_power_offload_callback_fn(void *context, tANI_U32 session_id, hdd_request_put(request); } -/* Callback function registered with PMC to know status of PMC request */ -static void iw_power_callback_fn (void *pContext, eHalStatus status) -{ - struct statsContext *pStatsContext; - - if (NULL == pContext) - { - hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Bad param, pContext [%pK]", - __func__, pContext); - return; - } - - pStatsContext = (struct statsContext *)pContext; - - /* there is a race condition that exists between this callback - function and the caller since the caller could time out either - before or while this code is executing. we use a spinlock to - serialize these actions */ - spin_lock(&hdd_context_lock); - - if (POWER_CONTEXT_MAGIC != pStatsContext->magic) - { - /* the caller presumably timed out so there is nothing we can do */ - spin_unlock(&hdd_context_lock); - hddLog(VOS_TRACE_LEVEL_WARN, - "%s: Invalid context, magic [%08x]", - __func__, pStatsContext->magic); - - if (ioctl_debug) - { - pr_info("%s: Invalid context, magic [%08x]\n", - __func__, pStatsContext->magic); - } - return; - } - - /* context is valid so caller is still waiting */ - - /* paranoia: invalidate the magic */ - pStatsContext->magic = 0; - - /* notify the caller */ - complete(&pStatsContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); -} - /* Callback function for tx per hit */ void hdd_tx_per_hit_cb (void *pCallbackContext) { @@ -3710,66 +3479,6 @@ void hdd_tx_per_hit_cb (void *pCallbackContext) wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail); } -void hdd_GetClassA_statisticsCB(void *pStats, void *pContext) -{ - struct statsContext *pStatsContext; - tCsrGlobalClassAStatsInfo *pClassAStats; - hdd_adapter_t *pAdapter; - - if (ioctl_debug) - { - pr_info("%s: pStats [%pK] pContext [%pK]\n", - __func__, pStats, pContext); - } - - if ((NULL == pStats) || (NULL == pContext)) - { - hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Bad param, pStats [%pK] pContext [%pK]", - __func__, pStats, pContext); - return; - } - - pClassAStats = pStats; - pStatsContext = pContext; - pAdapter = pStatsContext->pAdapter; - - /* there is a race condition that exists between this callback - function and the caller since the caller could time out either - before or while this code is executing. we use a spinlock to - serialize these actions */ - spin_lock(&hdd_context_lock); - - if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) - { - /* the caller presumably timed out so there is nothing we can do */ - spin_unlock(&hdd_context_lock); - hddLog(VOS_TRACE_LEVEL_WARN, - "%s: Invalid context, pAdapter [%pK] magic [%08x]", - __func__, pAdapter, pStatsContext->magic); - if (ioctl_debug) - { - pr_info("%s: Invalid context, pAdapter [%pK] magic [%08x]\n", - __func__, pAdapter, pStatsContext->magic); - } - return; - } - - /* context is valid so caller is still waiting */ - - /* paranoia: invalidate the magic */ - pStatsContext->magic = 0; - - /* copy over the stats. do so as a struct copy */ - pAdapter->hdd_stats.ClassA_stat = *pClassAStats; - - /* notify the caller */ - complete(&pStatsContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); -} - void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext) { struct linkspeedContext *pLinkSpeedContext; @@ -3820,74 +3529,122 @@ void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext) spin_unlock(&hdd_context_lock); } -VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) +struct class_a_stats { + tCsrGlobalClassAStatsInfo class_a_stats; +}; + +/** + * hdd_get_class_a_statistics_cb() - Get Class A stats callback function + * @stats: pointer to Class A stats + * @context: user context originally registered with SME (always the + * cookie from the request context) + * + * Return: None + */ +static void hdd_get_class_a_statistics_cb(void *stats, void *context) { - hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - eHalStatus hstatus; - unsigned long rc; - struct statsContext context; + struct hdd_request *request; + struct class_a_stats *priv; + tCsrGlobalClassAStatsInfo *returned_stats; - if (NULL == pAdapter) - { - hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); - return VOS_STATUS_E_FAULT; - } - if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) - { - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); - return VOS_STATUS_SUCCESS; - } + ENTER(); + if (ioctl_debug) { + pr_info("%s: stats [%pK], context [%pK]\n", + __func__, stats, context); + } - /* we are connected - prepare our callback context */ - init_completion(&context.completion); - context.pAdapter = pAdapter; - context.magic = STATS_CONTEXT_MAGIC; - /* query only for Class A statistics (which include link speed) */ - hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), - eCSR_HDD, - SME_GLOBAL_CLASSA_STATS, - hdd_GetClassA_statisticsCB, - 0, // not periodic - FALSE, //non-cached results - pHddStaCtx->conn_info.staId[0], - &context, - pAdapter->sessionId ); - if (eHAL_STATUS_SUCCESS != hstatus) - { - hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Unable to retrieve Class A statistics", - __func__); - /* we'll returned a cached value below */ - } - else - { - /* request was sent -- wait for the response */ - rc = wait_for_completion_timeout(&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - if (!rc) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("SME timed out while retrieving Class A statistics")); - } - } + if (NULL == stats) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, stats [%pK]", __func__, stats); + return; + } - /* either we never sent a request, we sent a request and received a - response or we sent a request and timed out. if we never sent a - request or if we sent a request and got a response, we want to - clear the magic out of paranoia. if we timed out there is a - race condition such that the callback function could be - executing at the same time we are. of primary concern is if the - callback function had already verified the "magic" but had not - yet set the completion variable when a timeout occurred. we - serialize these activities by invalidating the magic while - holding a shared spinlock which will cause us to block if the - callback is currently executing */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + request = hdd_request_get(context); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Obsolete request", __func__); + return; + } - /* either callback updated pAdapter stats or it has cached data */ - return VOS_STATUS_SUCCESS; + returned_stats = stats; + priv = hdd_request_priv(request); + priv->class_a_stats = *returned_stats; + hdd_request_complete(request); + hdd_request_put(request); + EXIT(); +} + +/** + * wlan_hdd_get_classAstats() - Get Class A statistics + * @pAdapter: adapter for which statistics are desired + * + * Return: VOS_STATUS_SUCCESS if adapter's Class A statistics were updated + */ +VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eHalStatus hstatus; + int ret; + void *cookie; + struct hdd_request *request; + struct class_a_stats *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; + + if (NULL == pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!",__func__); + return VOS_STATUS_SUCCESS; + } + + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Request allocation failure", __func__); + return VOS_STATUS_E_NOMEM; + } + cookie = hdd_request_cookie(request); + + /* query only for Class A statistics (which include link speed) */ + hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter), + eCSR_HDD, SME_GLOBAL_CLASSA_STATS, + hdd_get_class_a_statistics_cb, + 0, /* not periodic */ + FALSE, /* non-cached results */ + pHddStaCtx->conn_info.staId[0], + cookie, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != hstatus) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve Class A statistics", + __func__); + goto return_cached_results; + } + + /* request was sent -- wait for the response */ + ret = hdd_request_wait_for_response(request); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving Class A statistics")); + goto return_cached_results; + } + /* update the adapter with the fresh results */ + priv = hdd_request_priv(request); + pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats; + +return_cached_results: + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + hdd_request_put(request); + + return VOS_STATUS_SUCCESS; } struct station_stats { @@ -4251,101 +4008,99 @@ static int iw_get_isolation(struct net_device *dev, VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode) { - struct statsContext context; - eHalStatus status; - hdd_context_t *pHddCtx; + struct hdd_request *request; + void *cookie; + eHalStatus status; + hdd_context_t *pHddCtx; + static const struct hdd_request_params params = { + .priv_size = 0, + .timeout_ms = WLAN_WAIT_TIME_POWER, + }; - if (NULL == pAdapter) - { - hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL"); - return VOS_STATUS_E_FAULT; - } + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL"); + return VOS_STATUS_E_FAULT; + } - hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode); - pHddCtx = WLAN_HDD_GET_CTX(pAdapter); - if (pHddCtx->isLogpInProgress) { - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s:LOGP in Progress. Ignore!!!", __func__); - return VOS_STATUS_E_FAILURE; - } + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + return VOS_STATUS_E_FAILURE; + } - init_completion(&context.completion); + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Request allocation failure", __func__); + return VOS_STATUS_E_NOMEM; + } - context.pAdapter = pAdapter; - context.magic = POWER_CONTEXT_MAGIC; + cookie = hdd_request_cookie(request); - if (DRIVER_POWER_MODE_ACTIVE == mode) - { - hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering " - "Full Power", __func__); - status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), - iw_power_callback_fn, &context, - eSME_FULL_PWR_NEEDED_BY_HDD); - // Enter Full power command received from GUI this means we are disconnected - // Set PMC remainInPowerActiveTillDHCP flag to disable auto BMPS entry by PMC - sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE); - if (eHAL_STATUS_PMC_PENDING == status) - { - unsigned long rc; - /* request was sent -- wait for the response */ - rc = wait_for_completion_timeout( - &context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - - if (!rc) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("SME timed out while requesting full power")); - } - } - } - else if (DRIVER_POWER_MODE_AUTO == mode) - { - if (pHddCtx->cfg_ini->fIsBmpsEnabled) - { - hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ", - __func__); - // Enter BMPS command received from GUI this means DHCP is completed - // Clear PMC remainInPowerActiveTillDHCP flag to enable auto BMPS entry - sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), - FALSE); - status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), - iw_power_callback_fn, &context); - if (eHAL_STATUS_PMC_PENDING == status) - { - unsigned long rc; - /* request was sent -- wait for the response */ - rc = wait_for_completion_timeout( - &context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - if (!rc) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("SME timed out while requesting BMPS")); - } - } - } - else - { - hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not " - "enabled in the cfg"); - } - } + if (DRIVER_POWER_MODE_ACTIVE == mode) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering " + "Full Power", __func__); + status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_func, cookie, + eSME_FULL_PWR_NEEDED_BY_HDD); + /* + * Enter Full power command received from GUI this means we are + * disconnected. Set PMC remainInPowerActiveTillDHCP flag to + * disable auto BMPS entry by PMC + */ + sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE); + if (eHAL_STATUS_PMC_PENDING == status) + { + int rc; + /* request was sent -- wait for the response */ + rc = hdd_request_wait_for_response(request); + if (rc) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while requesting full power")); + } + } + else if (DRIVER_POWER_MODE_AUTO == mode) + { + if (pHddCtx->cfg_ini->fIsBmpsEnabled) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ", + __func__); + /* + * Enter BMPS command received from GUI this means DHCP + * is completed. Clear PMC remainInPowerActiveTillDHCP + * flag to enable auto BMPS entry. + */ + sme_SetDHCPTillPowerActiveFlag( + WLAN_HDD_GET_HAL_CTX(pAdapter), FALSE); + status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_func, cookie); + if (eHAL_STATUS_PMC_PENDING == status) + { + int rc; + /* request was sent -- wait for the response */ + rc = hdd_request_wait_for_response(request); + if (rc) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while requesting BMPS")); + } + } else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not " + "enabled in the cfg"); + } + } - /* either we never sent a request, we sent a request and received a - response or we sent a request and timed out. if we never sent a - request or if we sent a request and got a response, we want to - clear the magic out of paranoia. if we timed out there is a - race condition such that the callback function could be - executing at the same time we are. of primary concern is if the - callback function had already verified the "magic" but had not - yet set the completion variable when a timeout occurred. we - serialize these activities by invalidating the magic while - holding a shared spinlock which will cause us to block if the - callback is currently executing */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + hdd_request_put(request); - return VOS_STATUS_SUCCESS; + return VOS_STATUS_SUCCESS; } VOS_STATUS wlan_hdd_set_powersave(hdd_adapter_t *pAdapter, int mode) @@ -5843,111 +5598,97 @@ int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal, return 0; } -void hdd_GetTemperatureCB(int temperature, void *pContext) +void hdd_GetTemperatureCB(int temperature, void *cookie) { - struct statsContext *pTempContext; - hdd_adapter_t *pAdapter; - - ENTER(); - - if (NULL == pContext) { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("pContext is NULL")); - return; - } - - pTempContext = pContext; - pAdapter = pTempContext->pAdapter; - - /* there is a race condition that exists between this callback - function and the caller since the caller could time out either - before or while this code is executing. we use a spinlock to - serialize these actions */ - spin_lock(&hdd_context_lock); + struct hdd_request *request; + struct temperature_info *priv; - if ((NULL == pAdapter) || - (TEMP_CONTEXT_MAGIC != pTempContext->magic)) - { - /* the caller presumably timed out so there is nothing we can do */ - spin_unlock(&hdd_context_lock); - hddLog(VOS_TRACE_LEVEL_WARN, - FL("Invalid context, pAdapter [%pK] magic [%08x]"), - pAdapter, pTempContext->magic); - return; - } + ENTER(); - /* context is valid, update the temperature, ignore it if this was 0 */ - if (temperature != 0) { - pAdapter->temperature = temperature; - } + request = hdd_request_get(cookie); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Obsolete request", __func__); + return; + } + priv = hdd_request_priv(request); - /* notify the caller */ - complete(&pTempContext->completion); + priv->temperature = temperature; - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + hdd_request_complete(request); + hdd_request_put(request); - EXIT(); + EXIT(); } -VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, +VOS_STATUS wlan_hdd_get_temperature(hdd_adapter_t *adapter_ptr, union iwreq_data *wrqu, char *extra) { - eHalStatus hstatus; - struct statsContext tempContext; - unsigned long rc; - A_INT32 *pData = (A_INT32 *)extra; + eHalStatus hstatus; + int ret; + A_INT32 *data_ptr = (A_INT32 *)extra; + void *cookie; + struct hdd_request *request; + struct temperature_info *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; - ENTER(); + ENTER(); - if (NULL == pAdapter) - { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("pAdapter is NULL")); - return VOS_STATUS_E_FAULT; - } + if (NULL == adapter_ptr) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + return VOS_STATUS_E_FAULT; + } - /* prepare callback context and magic pattern */ - init_completion(&tempContext.completion); - tempContext.pAdapter = pAdapter; - tempContext.magic = TEMP_CONTEXT_MAGIC; + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Request allocation failure", __func__); + return VOS_STATUS_E_NOMEM; + } + cookie = hdd_request_cookie(request); - /* send get temperature request to sme */ - hstatus = sme_GetTemperature( - WLAN_HDD_GET_HAL_CTX(pAdapter), - &tempContext, - hdd_GetTemperatureCB); + /* send get temperature request to sme */ + hstatus = + sme_GetTemperature(WLAN_HDD_GET_HAL_CTX(adapter_ptr), + cookie, + hdd_GetTemperatureCB); - if (eHAL_STATUS_SUCCESS != hstatus) { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve temperature")); - } else { - /* request was sent -- wait for the response */ - rc = wait_for_completion_timeout(&tempContext.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - if (!rc) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("SME timed out while retrieving temperature")); - } - } - - /* either we never sent a request, we sent a request and received a - response or we sent a request and timed out. if we never sent a - request or if we sent a request and got a response, we want to - clear the magic out of paranoia. if we timed out there is a - race condition such that the callback function could be - executing at the same time we are. of primary concern is if the - callback function had already verified the "magic" but had not - yet set the completion variable when a timeout occurred. we - serialize these activities by invalidating the magic while - holding a shared spinlock which will cause us to block if the - callback is currently executing */ - spin_lock(&hdd_context_lock); - tempContext.magic = 0; - spin_unlock(&hdd_context_lock); + if (eHAL_STATUS_SUCCESS != hstatus) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Unable to retrieve temperature")); + } else { + /* request was sent -- wait for the response */ + ret = hdd_request_wait_for_response(request); + if (ret) { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("timeout when get temperature")); + /* we'll returned a cached value below */ + } else { + /* update the adapter with the fresh results */ + priv = hdd_request_priv(request); + /* ignore it if this was 0 */ + if (priv->temperature != 0) + adapter_ptr->temperature = + priv->temperature; + } + } + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + hdd_request_put(request); - /* update temperature */ - *pData = pAdapter->temperature; + /* update temperature */ + *data_ptr = adapter_ptr->temperature; - EXIT(); - return VOS_STATUS_SUCCESS; + EXIT(); + return VOS_STATUS_SUCCESS; } /* set param sub-ioctls */ @@ -11433,8 +11174,8 @@ static const iw_handler we_handler[] = (iw_handler) NULL, /* SIOCGIWNWID */ (iw_handler) iw_set_freq, /* SIOCSIWFREQ */ (iw_handler) iw_get_freq, /* SIOCGIWFREQ */ - (iw_handler) iw_set_mode, /* SIOCSIWMODE */ - (iw_handler) iw_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWMODE */ + (iw_handler) NULL, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ (iw_handler) NULL, /* SIOCGIWSENS */ (iw_handler) NULL, /* SIOCSIWRANGE */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h index 1456e379503..1dfff0f8ec7 100644 --- a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h @@ -32,7 +32,7 @@ * \brief Structures, function prototypes & definitions * for working with 802.11 Frames * This file was automatically generated by 'framesc' - * Thu Dec 28 13:33:15 2017 from the following file(s): + * Wed Jun 20 14:32:20 2018 from the following file(s): * * dot11f.frms * @@ -51,6 +51,10 @@ typedef tANI_U32 tDOT11F_U64[2]; # pragma warning (disable: 4214) /* nonstandard extension used */ #endif /* Microsoft C/C++ bit field types other than int */ +#if !defined unlikely +#define unlikely(x) (x) +#endif + /* * Frames Return Codes: * diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c index a5146ae1fb3..ec022c3ab82 100644 --- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -593,7 +593,7 @@ limCheckAndAddBssDescription(tpAniSirGlobal pMac, */ ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); - if (ieLen <= SIR_MAC_B_PR_SSID_OFFSET) + if (ieLen <= (SIR_MAC_B_PR_SSID_OFFSET + 2)) { limLog(pMac, LOGP, FL("RX packet has invalid length %d"), ieLen); @@ -644,18 +644,21 @@ limCheckAndAddBssDescription(tpAniSirGlobal pMac, limLog(pMac, LOG1, FL(" pHdr->addr3:"MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->addr3)); limLog( pMac, LOG1, FL("Save this entry in LFR cache")); - status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); + status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, + dontUpdateAll, ieLen - 2); } else #endif //If it is not scanning, only save unique results if (pMac->lim.gLimReturnUniqueResults || (!fScanning)) { - status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, dontUpdateAll); + status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, + dontUpdateAll, ieLen - 2); } else { - status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); + status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, + dontUpdateAll, ieLen - 2); } if(fScanning) @@ -796,7 +799,7 @@ limInitHashTable(tpAniSirGlobal pMac) eHalStatus limLookupNaddHashEntry(tpAniSirGlobal pMac, tLimScanResultNode *pBssDescr, tANI_U8 action, - tANI_U8 dontUpdateAll) + tANI_U8 dontUpdateAll, tANI_U32 ie_len) { tANI_U8 index, ssidLen = 0; tANI_U8 found = false; @@ -812,6 +815,11 @@ limLookupNaddHashEntry(tpAniSirGlobal pMac, //ieFields start with TLV of SSID IE ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); + if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) { + limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"), + ssidLen, ie_len); + return eHAL_STATUS_FAILURE; + } pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) @@ -825,6 +833,8 @@ limLookupNaddHashEntry(tpAniSirGlobal pMac, // matching band to update new channel info (vos_chan_to_band(pBssDescr->bssDescription.channelId) == vos_chan_to_band(ptemp->bssDescription.channelId)) && + (((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) == + ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) && vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), (tANI_U8) (ssidLen + 1)) && @@ -1035,9 +1045,9 @@ limInitLfrHashTable(tpAniSirGlobal pMac) eHalStatus limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, tLimScanResultNode *pBssDescr, tANI_U8 action, - tANI_U8 dontUpdateAll) + tANI_U8 dontUpdateAll, tANI_U32 ie_len) { - tANI_U8 index, ssidLen = 0; + tANI_U8 index, ssidLen = 0; tLimScanResultNode *ptemp, *pprev; tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; int idx, len; @@ -1050,6 +1060,11 @@ limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, //ieFields start with TLV of SSID IE ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); + if ((ssidLen > ie_len) || (ssidLen > DOT11F_IE_SSID_MAX_LEN)) { + limLog(pMac, LOGE, FL("SSID length %d, IE overall Length %d"), + ssidLen, ie_len); + return eHAL_STATUS_FAILURE; + } pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) @@ -1062,6 +1077,8 @@ limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, sizeof(tSirMacAddr))) && //matching BSSID (pBssDescr->bssDescription.channelId == ptemp->bssDescription.channelId) && + (((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1) == + ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1)) && vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), (tANI_U8) (ssidLen + 1)) && diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h index cbf08f1c45f..020085c9bcd 100644 --- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012, 2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -44,7 +44,7 @@ tANI_U8 limScanHashFunction(tSirMacAddr); void limInitHashTable(tpAniSirGlobal); eHalStatus - limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); + limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8, tANI_U32); void limDeleteHashEntry(tLimScanResultNode *); void limFlushp2pScanResults(tpAniSirGlobal); void limDeleteCachedScanResults(tpAniSirGlobal); @@ -54,7 +54,7 @@ void limReInitScanResults(tpAniSirGlobal); #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD void limInitLfrHashTable(tpAniSirGlobal); eHalStatus - limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); + limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8, tANI_U32); void limDeleteLfrHashEntry(tLimScanResultNode *); void limDeleteCachedLfrScanResults(tpAniSirGlobal); void limReInitLfrScanResults(tpAniSirGlobal); diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c index b5335d6188e..c0c86a5a9b3 100644 --- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -332,7 +332,9 @@ limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac, LOG1, FL("Only RSN IE is present")); dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2], - (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe); + pRSNie->rsnIEdata[1], + &pSessionEntry->gStartBssRSNIe); + return true; } else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) && (pRSNie->rsnIEdata[0] == SIR_MAC_WPA_EID)) @@ -341,8 +343,10 @@ limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac, LOG1, FL("Only WPA IE is present")); - dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[6],(tANI_U8)pRSNie->length-4, - &pSessionEntry->gStartBssWPAIe); + dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[6], + pRSNie->rsnIEdata[1] - 4, + &pSessionEntry->gStartBssWPAIe); + return true; } // Check validity of WPA IE @@ -365,7 +369,7 @@ limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac, { /* Both RSN and WPA IEs are present */ dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2], - (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe); + pRSNie->rsnIEdata[1], &pSessionEntry->gStartBssRSNIe); dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[wpaIndex + 6], pRSNie->rsnIEdata[wpaIndex + 1]-4, diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/lim_process_fils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/lim_process_fils.c index 5ab7e27bab0..fe7b5f4584a 100644 --- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/lim_process_fils.c +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/lim_process_fils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1412,6 +1412,11 @@ static VOS_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx, elem_len = *temp_ie++; rem_len -= 2; + if (elem_len < KDE_IE_DATA_OFFSET) { + limLog(max_ctx, LOGE, FL("Not enough len to parse elem_len %d"), + elem_len); + return VOS_STATUS_E_FAILURE; + } if (lim_check_if_vendor_oui_match(mac_ctx, KDE_OUI_TYPE, KDE_OUI_TYPE_SIZE, current_ie, elem_len)) { data_type = *(temp_ie + KDE_DATA_TYPE_OFFSET); @@ -1420,6 +1425,12 @@ static VOS_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx, switch(data_type) { /* TODO - is anymore KDE type expected */ case DATA_TYPE_GTK: + if (data_len < GTK_OFFSET) { + limLog(mac_ctx, LOGE, + FL("Invalid KDE data_len %d"), + data_len); + return VOS_STATUS_E_FAILURE; + } limLog(mac_ctx, LOG1, FL("GTK found ")); vos_mem_copy(fils_info->gtk, (ie_data + GTK_OFFSET), (data_len - @@ -1427,6 +1438,12 @@ static VOS_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx, fils_info->gtk_len = (data_len - GTK_OFFSET); break; case DATA_TYPE_IGTK: + if (data_len < IGTK_OFFSET) { + limLog(mac_ctx, LOGE, + FL("Invalid KDE data_len %d"), + data_len); + return VOS_STATUS_E_FAILURE; + } limLog(mac_ctx, LOG1, FL("IGTK found")); fils_info->igtk_len = (data_len - IGTK_OFFSET); vos_mem_copy(fils_info->igtk, (ie_data + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c index db7c8fe3c86..7c4bf80e6ef 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c @@ -4587,7 +4587,7 @@ static int wma_extscan_cached_results_event_handler(void *handle, struct extscan_cached_scan_results empty_cachelist; wmi_extscan_wlan_descriptor *src_hotlist; wmi_extscan_rssi_info *src_rssi; - int numap, i, moredata, scan_ids_cnt; + int i, moredata, scan_ids_cnt; int buf_len; u_int32_t total_len; bool excess_data = false; @@ -4601,7 +4601,7 @@ static int wma_extscan_cached_results_event_handler(void *handle, if (!pMac->sme.pExtScanIndCb) { WMA_LOGE("%s: Callback not registered", __func__); return -EINVAL; - } + } param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *) cmd_param_info; if (!param_buf) { @@ -4612,39 +4612,16 @@ static int wma_extscan_cached_results_event_handler(void *handle, event = param_buf->fixed_param; src_hotlist = param_buf->bssid_list; src_rssi = param_buf->rssi_list; - numap = event->num_entries_in_page; WMA_LOGI("Total_entries: %u first_entry_index: %u num_entries_in_page: %u", - event->total_entries, event->first_entry_index, numap); - if (!src_hotlist || !src_rssi || !numap) { + event->total_entries, event->first_entry_index, event->num_entries_in_page); + if (!src_hotlist || !src_rssi || !event->num_entries_in_page) { WMA_LOGW("%s: Cached results empty, send 0 results", __func__); goto noresults; - } - - if (event->first_entry_index + - event->num_entries_in_page < event->total_entries) - moredata = 1; - else - moredata = 0; - - dest_cachelist = vos_mem_malloc(sizeof(*dest_cachelist)); - if (!dest_cachelist) { - WMA_LOGE("%s: vos_mem_malloc failed", __func__); - return -ENOMEM; } - vos_mem_zero(dest_cachelist, sizeof(*dest_cachelist)); - dest_cachelist->request_id = event->request_id; - dest_cachelist->more_data = moredata; - - scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info); - WMA_LOGI("scan_ids_cnt %d", scan_ids_cnt); - dest_cachelist->num_scan_ids = scan_ids_cnt; - if (event->num_entries_in_page > (WMA_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist)) { WMA_LOGE("%s:excess num_entries_in_page %d in WMI event", __func__, event->num_entries_in_page); - vos_mem_free(dest_cachelist); - VOS_ASSERT(0); return -EINVAL; } else { total_len = sizeof(*event) + @@ -4671,11 +4648,28 @@ static int wma_extscan_cached_results_event_handler(void *handle, } if (excess_data) { WMA_LOGE("%s:excess data in WMI event", __func__); - vos_mem_free(dest_cachelist); - VOS_ASSERT(0); return -EINVAL; } + if (event->first_entry_index + + event->num_entries_in_page < event->total_entries) + moredata = 1; + else + moredata = 0; + + dest_cachelist = vos_mem_malloc(sizeof(*dest_cachelist)); + if (!dest_cachelist) { + WMA_LOGE("%s: vos_mem_malloc failed", __func__); + return -ENOMEM; + } + vos_mem_zero(dest_cachelist, sizeof(*dest_cachelist)); + dest_cachelist->request_id = event->request_id; + dest_cachelist->more_data = moredata; + + scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info); + WMA_LOGD("scan_ids_cnt %d", scan_ids_cnt); + dest_cachelist->num_scan_ids = scan_ids_cnt; + buf_len = sizeof(*dest_result) * scan_ids_cnt; dest_cachelist->result = vos_mem_malloc(buf_len); if (!dest_cachelist->result) { @@ -4983,7 +4977,7 @@ static int wma_unified_link_iface_stats_event_handler(void *handle, WMA_LOGA("%s: Invalid param_tlvs for Iface Stats", __func__); return -EINVAL; } - if (link_stats->num_ac >= WIFI_AC_MAX) { + if (link_stats->num_ac > WIFI_AC_MAX) { WMA_LOGE("%s: Excess data received from firmware num_ac %d", __func__, link_stats->num_ac); return -EINVAL; @@ -36139,7 +36133,10 @@ int wma_scpc_event_handler(void *handle, u_int8_t *event_buf, u_int32_t len) param_buf = (WMI_PDEV_UTF_SCPC_EVENTID_param_tlvs *)event_buf; scpc_event = param_buf->fixed_param; length = len - sizeof(wmi_scpc_event_fixed_param); - + if (length < sizeof(u_int32_t)) { + WMA_LOGE("%s: invalid length", __func__); + return -EINVAL; + } buf = (u_int8_t *)scpc_event + sizeof(wmi_scpc_event_fixed_param); @@ -36148,21 +36145,30 @@ int wma_scpc_event_handler(void *handle, u_int8_t *event_buf, u_int32_t len) /* skip the tag */ buf += sizeof(u_int32_t); + length -= sizeof(u_int32_t); + if (length < sizeof(struct _bd)) { + WMA_LOGE("%s: invalid length", __func__); + return -EINVAL; + } + i = n = 0; - bd_data = (struct _bd *)&buf[n]; - n += roundup((sizeof(struct _bd) + bd_data->length), 4); - while ((n < length) && (i < scpc_event->num_patch)) { + while ((n <= length - sizeof(struct _bd)) && (i < scpc_event->num_patch)) { bd_data = (struct _bd *)&buf[n]; WMA_LOGD("%s: board data patch%i, offset= %d, length= %d.\n", __func__, i, bd_data->offset, bd_data->length); + if (bd_data->length > length - sizeof(struct _bd) - n) + break; + /* cache the data section */ vos_cache_boarddata(bd_data->offset, - bd_data->length, bd_data->data); - - n += roundup((sizeof(struct _bd) + bd_data->length), 4); + bd_data->length, bd_data->data); + len = roundup((sizeof(struct _bd) + bd_data->length), 4); + if (len > length - n) + break; + n += len; i++; } diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c index 0d25f085c5e..6f4e9670892 100644 --- a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c @@ -30,7 +30,7 @@ * \brief Structures, functions & definitions for * working with 802.11 Frames * This file was automatically generated by 'framesc' - * Thu Dec 28 13:33:15 2017 from the following file(s): + * Wed Jun 20 14:32:20 2018 from the following file(s): * * dot11f.frms * @@ -1011,6 +1011,11 @@ tANI_U32 dot11fUnpackTlvAuthorizedMACs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_ { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; @@ -1029,6 +1034,11 @@ tANI_U32 dot11fUnpackTlvVersion2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tl tANI_U32 status = DOT11F_PARSE_SUCCESS; tANI_U8 tmp8__; pDst->present = 1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp8__ = *pBuf; pBuf += 1; tlvlen -= 1; @@ -1051,6 +1061,11 @@ tANI_U32 dot11fUnpackTlvChannelList(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); pBuf += 3; tlvlen -= (tANI_U8)3; @@ -1080,9 +1095,19 @@ tANI_U32 dot11fUnpackTlvConfigurationTimeout(tpAniSirGlobal pCtx, tANI_U8 *pBuf, { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->GOConfigTimeout = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->CLConfigTimeout = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; @@ -1120,9 +1145,19 @@ tANI_U32 dot11fUnpackTlvExtendedListenTiming(tpAniSirGlobal pCtx, tANI_U8 *pBuf, { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->availibilityPeriod, pBuf, 0); pBuf += 2; tlvlen -= (tANI_U8)2; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->availibilityInterval, pBuf, 0); pBuf += 2; tlvlen -= (tANI_U8)2; @@ -1140,6 +1175,11 @@ tANI_U32 dot11fUnpackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal pCtx, tANI_U8 { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->P2PInterfaceAddress, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; @@ -1157,12 +1197,27 @@ tANI_U32 dot11fUnpackTlvListenChannel(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); pBuf += 3; tlvlen -= (tANI_U8)3; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->regulatoryClass = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->channel = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; @@ -1240,9 +1295,19 @@ tANI_U32 dot11fUnpackTlvNoticeOfAbsence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->index = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->CTSWindowOppPS = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; @@ -1266,12 +1331,27 @@ tANI_U32 dot11fUnpackTlvOperatingChannel(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tAN { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); pBuf += 3; tlvlen -= (tANI_U8)3; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->regulatoryClass = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->channel = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; @@ -1286,9 +1366,19 @@ tANI_U32 dot11fUnpackTlvP2PCapability(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->deviceCapability = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->groupCapability = *pBuf; pBuf += 1; tlvlen -= (tANI_U8)1; @@ -1303,6 +1393,11 @@ tANI_U32 dot11fUnpackTlvP2PDeviceId(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; @@ -1322,12 +1417,27 @@ tANI_U32 dot11fUnpackTlvP2PDeviceInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->configMethod, pBuf, 0); pBuf += 2; tlvlen -= (tANI_U8)2; + if (unlikely(tlvlen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->primaryDeviceType, pBuf, 8); pBuf += 8; tlvlen -= (tANI_U8)8; @@ -1348,6 +1458,11 @@ tANI_U32 dot11fUnpackTlvP2PGroupBssid(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->P2PGroupBssid, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; @@ -1362,6 +1477,11 @@ tANI_U32 dot11fUnpackTlvP2PGroupId(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->deviceAddress, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; @@ -1404,12 +1524,27 @@ tANI_U32 dot11fUnpackTlvPrimaryDeviceType(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA tANI_U32 status = DOT11F_PARSE_SUCCESS; (void)pBuf; (void)tlvlen; /* Shutup the compiler */ pDst->present = 1; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->primary_category, pBuf, 1); pBuf += 2; tlvlen -= (tANI_U8)2; + if (unlikely(tlvlen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4); pBuf += 4; tlvlen -= (tANI_U8)4; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->sub_category, pBuf, 1); pBuf += 2; tlvlen -= (tANI_U8)2; @@ -1427,12 +1562,27 @@ tANI_U32 dot11fUnpackTlvRequestDeviceType(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->primary_category, pBuf, 1); pBuf += 2; tlvlen -= (tANI_U8)2; + if (unlikely(tlvlen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4); pBuf += 4; tlvlen -= (tANI_U8)4; + if (unlikely(tlvlen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->sub_category, pBuf, 1); pBuf += 2; tlvlen -= (tANI_U8)2; @@ -1479,6 +1629,11 @@ tANI_U32 dot11fUnpackTlvUUID_E(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvl { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16); pBuf += 16; tlvlen -= (tANI_U8)16; @@ -1493,6 +1648,11 @@ tANI_U32 dot11fUnpackTlvUUID_R(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvl { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16); pBuf += 16; tlvlen -= (tANI_U8)16; @@ -1514,6 +1674,11 @@ tANI_U32 dot11fUnpackTlvVendorExtension(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->vendorId, pBuf, 3); pBuf += 3; tlvlen -= (tANI_U8)3; @@ -1535,6 +1700,11 @@ tANI_U32 dot11fUnpackTlvVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlv tANI_U32 status = DOT11F_PARSE_SUCCESS; tANI_U8 tmp9__; pDst->present = 1; + if (unlikely(tlvlen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp9__ = *pBuf; pBuf += 1; tlvlen -= 1; @@ -1554,6 +1724,11 @@ tANI_U32 dot11fUnpackTlvP2PInterface(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U1 { tANI_U32 status = DOT11F_PARSE_SUCCESS; pDst->present = 1; + if (unlikely(tlvlen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); pBuf += 6; tlvlen -= (tANI_U8)6; @@ -1573,6 +1748,11 @@ tANI_U32 dot11fUnpackIeCondensedCountryStr(tpAniSirGlobal pCtx, tANI_U8 *pBuf, t (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->countryStr, pBuf, 2); (void)pCtx; return status; @@ -1588,14 +1768,29 @@ tANI_U32 dot11fUnpackIeGTK(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp10__, pBuf, 0); pBuf += 2; ielen -= 2; pDst->keyId = tmp10__ >> 0 & 0x3; pDst->reserved = tmp10__ >> 2 & 0x3feb; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->keyLength = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->RSC, pBuf, 8); pBuf += 8; ielen -= (tANI_U8)8; @@ -1619,15 +1814,35 @@ tANI_U32 dot11fUnpackIeIGTK(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, t (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->keyID, pBuf, 2); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->IPN, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->keyLength = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 24)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->key, pBuf, 24); (void)pCtx; return status; @@ -1642,6 +1857,11 @@ tANI_U32 dot11fUnpackIeMccChanInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 i (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->channel = *pBuf; (void)pCtx; return status; @@ -1676,6 +1896,11 @@ tANI_U32 dot11fUnpackIeR1KH_ID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->PMK_R1_ID, pBuf, 6); (void)pCtx; return status; @@ -1690,9 +1915,19 @@ tANI_U32 dot11fUnpackIeSub20Info(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->capability = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->csa_chanwidth = *pBuf; (void)pCtx; return status; @@ -1707,9 +1942,19 @@ tANI_U32 dot11fUnpackIeTSFInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->TsfOffset, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->BeaconIntvl, pBuf, 0); (void)pCtx; return status; @@ -1724,6 +1969,11 @@ tANI_U32 dot11fUnpackIeAPChannelReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_ (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->regulatoryClass = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -1747,6 +1997,11 @@ tANI_U32 dot11fUnpackIeBcnReportingDetail(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->reportingDetail = *pBuf; (void)pCtx; return status; @@ -1781,9 +2036,19 @@ tANI_U32 dot11fUnpackIeBeaconReporting(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_ (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->reportingCondition = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->threshold = *pBuf; (void)pCtx; return status; @@ -1798,6 +2063,11 @@ tANI_U32 dot11fUnpackIeMeasurementPilot(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurementPilot = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -1816,6 +2086,11 @@ tANI_U32 dot11fUnpackIeMultiBssid(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->maxBSSIDIndicator = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -1834,12 +2109,27 @@ tANI_U32 dot11fUnpackIeRICData(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->Identifier = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->resourceDescCount = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->statusCode, pBuf, 0); (void)pCtx; return status; @@ -1854,6 +2144,11 @@ tANI_U32 dot11fUnpackIeRICDescriptor(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->resourceType = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -1877,6 +2172,11 @@ tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp11__ = *pBuf; pBuf += 1; ielen -= 1; @@ -1888,6 +2188,11 @@ tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->BeaconActive = tmp11__ >> 5 & 0x1; pDst->BeaconTable = tmp11__ >> 6 & 0x1; pDst->BeaconRepCond = tmp11__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp12__ = *pBuf; pBuf += 1; ielen -= 1; @@ -1899,6 +2204,11 @@ tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->LCIAzimuth = tmp12__ >> 5 & 0x1; pDst->TCMCapability = tmp12__ >> 6 & 0x1; pDst->triggeredTCM = tmp12__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp13__ = *pBuf; pBuf += 1; ielen -= 1; @@ -1906,6 +2216,11 @@ tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->RRMMIBEnabled = tmp13__ >> 1 & 0x1; pDst->operatingChanMax = tmp13__ >> 2 & 0x7; pDst->nonOperatinChanMax = tmp13__ >> 5 & 0x7; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp14__ = *pBuf; pBuf += 1; ielen -= 1; @@ -1915,6 +2230,11 @@ tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->RCPIMeasurement = tmp14__ >> 5 & 0x1; pDst->RSNIMeasurement = tmp14__ >> 6 & 0x1; pDst->BssAvgAccessDelay = tmp14__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp15__ = *pBuf; pDst->BSSAvailAdmission = tmp15__ >> 0 & 0x1; pDst->AntennaInformation = tmp15__ >> 1 & 0x1; @@ -1974,6 +2294,11 @@ tANI_U32 dot11fUnpackIeSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp16__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -1981,15 +2306,35 @@ tANI_U32 dot11fUnpackIeSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele pDst->tsid = tmp16__ >> 1 & 0xf; pDst->direction = tmp16__ >> 5 & 0x3; pDst->reserved = tmp16__ >> 7 & 0x1ff; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->service_interval, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->spec_interval, pBuf, 0); (void)pCtx; return status; @@ -2004,70 +2349,165 @@ tANI_U32 dot11fUnpackIeTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->user_priority = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->classifier_type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->classifier_mask = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; switch (pDst->classifier_type) { case 0: + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; break; case 1: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; switch (pDst->info.IpParams.version) { case 4: + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.params.IpV4Params.proto = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.params.IpV4Params.reserved = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; break; case 6: + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3); pBuf += 3; ielen -= (tANI_U8)3; @@ -2075,6 +2515,11 @@ tANI_U32 dot11fUnpackIeTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, } break; case 2: + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; @@ -2096,6 +2541,11 @@ tANI_U32 dot11fUnpackIeTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->delay, pBuf, 0); (void)pCtx; return status; @@ -2113,6 +2563,11 @@ tANI_U32 dot11fUnpackIeTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp17__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -2124,55 +2579,135 @@ tANI_U32 dot11fUnpackIeTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->psb = tmp17__ >> 10 & 0x1; pDst->user_priority = tmp17__ >> 11 & 0x7; pDst->tsinfo_ack_pol = tmp17__ >> 14 & 0x3; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp18__ = *pBuf; pBuf += 1; ielen -= 1; pDst->schedule = tmp18__ >> 0 & 0x1; pDst->unused = tmp18__ >> 1 & 0x7f; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp19__, pBuf, 0); pBuf += 2; ielen -= 2; pDst->size = tmp19__ >> 0 & 0x7fff; pDst->fixed = tmp19__ >> 15 & 0x1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->min_service_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->max_service_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->suspension_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->burst_size, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->delay_bound, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->medium_time, pBuf, 0); (void)pCtx; return status; @@ -2190,6 +2725,11 @@ tANI_U32 dot11fUnpackIeVHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &tmp20__, pBuf, 0); pBuf += 4; ielen -= 4; @@ -2213,17 +2753,37 @@ tANI_U32 dot11fUnpackIeVHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen pDst->rxAntPattern = tmp20__ >> 28 & 0x1; pDst->txAntPattern = tmp20__ >> 29 & 0x1; pDst->reserved1 = tmp20__ >> 30 & 0x3; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->rxMCSMap, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp21__, pBuf, 0); pBuf += 2; ielen -= 2; pDst->rxHighSupDataRate = tmp21__ >> 0 & 0x1fff; pDst->reserved2 = tmp21__ >> 13 & 0x7; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->txMCSMap, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp22__, pBuf, 0); pDst->txSupDataRate = tmp22__ >> 0 & 0x1fff; pDst->reserved3 = tmp22__ >> 13 & 0x7; @@ -2240,15 +2800,35 @@ tANI_U32 dot11fUnpackIeVHTOperation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->chanWidth = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->chanCenterFreqSeg1 = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->chanCenterFreqSeg2 = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->basicMCSSet, pBuf, 0); (void)pCtx; return status; @@ -2264,6 +2844,11 @@ tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 i (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -2272,6 +2857,11 @@ tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 i pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp23__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -2279,15 +2869,35 @@ tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 i pDst->tsid = tmp23__ >> 1 & 0xf; pDst->direction = tmp23__ >> 5 & 0x3; pDst->reserved = tmp23__ >> 7 & 0x1ff; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->service_interval, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->spec_interval, pBuf, 0); (void)pCtx; return status; @@ -2302,6 +2912,11 @@ tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -2310,70 +2925,165 @@ tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->user_priority = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->classifier_type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->classifier_mask = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; switch (pDst->classifier_type) { case 0: + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; break; case 1: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; switch (pDst->info.IpParams.version) { case 4: + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.params.IpV4Params.proto = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->info.IpParams.params.IpV4Params.reserved = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; break; case 6: + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3); pBuf += 3; ielen -= (tANI_U8)3; @@ -2381,6 +3091,11 @@ tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele } break; case 2: + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; @@ -2399,6 +3114,11 @@ tANI_U32 dot11fUnpackIeWMMTCLASPROC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -2407,6 +3127,11 @@ tANI_U32 dot11fUnpackIeWMMTCLASPROC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->processing = *pBuf; (void)pCtx; return status; @@ -2421,6 +3146,11 @@ tANI_U32 dot11fUnpackIeWMMTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -2429,6 +3159,11 @@ tANI_U32 dot11fUnpackIeWMMTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->delay, pBuf, 0); (void)pCtx; return status; @@ -2446,6 +3181,11 @@ tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -2454,6 +3194,11 @@ tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp24__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -2465,55 +3210,135 @@ tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele pDst->psb = tmp24__ >> 10 & 0x1; pDst->user_priority = tmp24__ >> 11 & 0x7; pDst->tsinfo_ack_pol = tmp24__ >> 14 & 0x3; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp25__ = *pBuf; pBuf += 1; ielen -= 1; pDst->tsinfo_rsvd = tmp25__ >> 0 & 0x7f; pDst->burst_size_defn = tmp25__ >> 7 & 0x1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp26__, pBuf, 0); pBuf += 2; ielen -= 2; pDst->size = tmp26__ >> 0 & 0x7fff; pDst->fixed = tmp26__ >> 15 & 0x1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->min_service_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->max_service_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->suspension_int, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->burst_size, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->delay_bound, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->medium_time, pBuf, 0); (void)pCtx; return status; @@ -2528,12 +3353,27 @@ tANI_U32 dot11fUnpackIeWiderBWChanSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->newChanWidth = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->newCenterChanFreq0 = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->newCenterChanFreq1 = *pBuf; (void)pCtx; return status; @@ -2568,6 +3408,11 @@ tANI_U32 dot11fUnpackIeAID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->assocId, pBuf, 0); (void)pCtx; return status; @@ -2582,15 +3427,35 @@ tANI_U32 dot11fUnpackIeCFParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->cfp_count = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->cfp_period = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->cfp_maxduration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->cfp_durremaining, pBuf, 0); (void)pCtx; return status; @@ -2625,12 +3490,27 @@ tANI_U32 dot11fUnpackIeChanSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->switchMode = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->newChannel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->switchCount = *pBuf; (void)pCtx; return status; @@ -2675,6 +3555,11 @@ tANI_U32 dot11fUnpackIeCountry(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 3)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->country, pBuf, 3); pBuf += 3; ielen -= (tANI_U8)3; @@ -2717,12 +3602,27 @@ tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->qos = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->reserved = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp27__ = *pBuf; pBuf += 1; ielen -= 1; @@ -2730,14 +3630,29 @@ tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->acbe_acm = tmp27__ >> 4 & 0x1; pDst->acbe_aci = tmp27__ >> 5 & 0x3; pDst->unused1 = tmp27__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp28__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acbe_acwmin = tmp28__ >> 0 & 0xf; pDst->acbe_acwmax = tmp28__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp29__ = *pBuf; pBuf += 1; ielen -= 1; @@ -2745,14 +3660,29 @@ tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->acbk_acm = tmp29__ >> 4 & 0x1; pDst->acbk_aci = tmp29__ >> 5 & 0x3; pDst->unused2 = tmp29__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp30__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acbk_acwmin = tmp30__ >> 0 & 0xf; pDst->acbk_acwmax = tmp30__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp31__ = *pBuf; pBuf += 1; ielen -= 1; @@ -2760,14 +3690,29 @@ tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->acvi_acm = tmp31__ >> 4 & 0x1; pDst->acvi_aci = tmp31__ >> 5 & 0x3; pDst->unused3 = tmp31__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp32__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acvi_acwmin = tmp32__ >> 0 & 0xf; pDst->acvi_acwmax = tmp32__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp33__ = *pBuf; pBuf += 1; ielen -= 1; @@ -2775,11 +3720,21 @@ tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 pDst->acvo_acm = tmp33__ >> 4 & 0x1; pDst->acvo_aci = tmp33__ >> 5 & 0x3; pDst->unused4 = tmp33__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp34__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acvo_acwmin = tmp34__ >> 0 & 0xf; pDst->acvo_acwmax = tmp34__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); (void)pCtx; return status; @@ -2795,6 +3750,11 @@ tANI_U32 dot11fUnpackIeERPInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp35__ = *pBuf; pDst->non_erp_present = tmp35__ >> 0 & 0x1; pDst->use_prot = tmp35__ >> 1 & 0x1; @@ -2834,9 +3794,19 @@ tANI_U32 dot11fUnpackIeESERadMgmtCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->mgmt_state = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp36__ = *pBuf; pDst->mbssid_mask = tmp36__ >> 0 & 0x7; pDst->reserved = tmp36__ >> 3 & 0x1f; @@ -2853,12 +3823,27 @@ tANI_U32 dot11fUnpackIeESETrafStrmMet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->tsid = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->state = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->msmt_interval, pBuf, 0); (void)pCtx; return status; @@ -2873,6 +3858,11 @@ tANI_U32 dot11fUnpackIeESETrafStrmRateSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->tsid = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -2896,9 +3886,19 @@ tANI_U32 dot11fUnpackIeESETxmitPower(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->power_limit = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->reserved = *pBuf; (void)pCtx; return status; @@ -2913,6 +3913,11 @@ tANI_U32 dot11fUnpackIeESEVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; (void)pCtx; return status; @@ -2980,15 +3985,35 @@ tANI_U32 dot11fUnpackIeFHParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->dwell_time, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->hop_set = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->hop_pattern = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->hop_index = *pBuf; (void)pCtx; return status; @@ -3003,9 +4028,19 @@ tANI_U32 dot11fUnpackIeFHParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->radix = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->nchannels = *pBuf; (void)pCtx; return status; @@ -3020,15 +4055,35 @@ tANI_U32 dot11fUnpackIeFHPattTable(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 i (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->flag = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->nsets = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->modulus = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->offset = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -3065,17 +4120,37 @@ tANI_U32 dot11fUnpackIeFTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp37__, pBuf, 0); pBuf += 2; ielen -= 2; pDst->reserved = tmp37__ >> 0 & 0xff; pDst->IECount = tmp37__ >> 8 & 0xff; + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->MIC, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; + if (unlikely(ielen < 32)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->Anonce, pBuf, 32); pBuf += 32; ielen -= (tANI_U8)32; + if (unlikely(ielen < 32)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->Snonce, pBuf, 32); pBuf += 32; ielen -= (tANI_U8)32; @@ -3100,6 +4175,11 @@ tANI_U32 dot11fUnpackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp38__ = *pBuf; pDst->infoRequest = tmp38__ >> 0 & 0x1; pDst->fortyMHzIntolerant = tmp38__ >> 1 & 0x1; @@ -3120,6 +4200,11 @@ tANI_U32 dot11fUnpackIeHT2040BSSIntolerantReport(tpAniSirGlobal pCtx, tANI_U8 *p (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->operatingClass = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -3148,6 +4233,11 @@ tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp39__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -3165,15 +4255,30 @@ tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->psmp = tmp39__ >> 13 & 0x1; pDst->stbcControlFrame = tmp39__ >> 14 & 0x1; pDst->lsigTXOPProtection = tmp39__ >> 15 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp40__ = *pBuf; pBuf += 1; ielen -= 1; pDst->maxRxAMPDUFactor = tmp40__ >> 0 & 0x3; pDst->mpduDensity = tmp40__ >> 2 & 0x7; pDst->reserved1 = tmp40__ >> 5 & 0x7; + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->supportedMCSSet, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp41__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -3182,6 +4287,11 @@ tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->reserved2 = tmp41__ >> 3 & 0x1f; pDst->mcsFeedback = tmp41__ >> 8 & 0x3; pDst->reserved3 = tmp41__ >> 10 & 0x3f; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &tmp42__, pBuf, 0); pBuf += 4; ielen -= 4; @@ -3201,6 +4311,11 @@ tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->uncompressedSteeringMatrixBFAntennae = tmp42__ >> 21 & 0x3; pDst->compressedSteeringMatrixBFAntennae = tmp42__ >> 23 & 0x3; pDst->reserved4 = tmp42__ >> 25 & 0x7f; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp43__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3235,9 +4350,19 @@ tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->primaryChannel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp44__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3246,6 +4371,11 @@ tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->rifsMode = tmp44__ >> 3 & 0x1; pDst->controlledAccessOnly = tmp44__ >> 4 & 0x1; pDst->serviceIntervalGranularity = tmp44__ >> 5 & 0x7; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp45__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -3254,6 +4384,11 @@ tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->transmitBurstLimit = tmp45__ >> 3 & 0x1; pDst->obssNonHTStaPresent = tmp45__ >> 4 & 0x1; pDst->reserved = tmp45__ >> 5 & 0x7ff; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp46__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -3264,6 +4399,11 @@ tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, pDst->pcoActive = tmp46__ >> 10 & 0x1; pDst->pcoPhase = tmp46__ >> 11 & 0x1; pDst->reserved2 = tmp46__ >> 12 & 0xf; + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->basicMCSSet, pBuf, 16); pBuf += 16; ielen -= (tANI_U8)16; @@ -3287,6 +4427,11 @@ tANI_U32 dot11fUnpackIeIBSSParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->atim, pBuf, 0); (void)pCtx; return status; @@ -3301,12 +4446,27 @@ tANI_U32 dot11fUnpackIeLinkIdentifier(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->InitStaAddr, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->RespStaAddr, pBuf, 6); (void)pCtx; return status; @@ -3333,9 +4493,19 @@ tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tAN (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->token = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp47__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3343,6 +4513,11 @@ tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tAN pDst->incapable = tmp47__ >> 1 & 0x1; pDst->refused = tmp47__ >> 2 & 0x1; pDst->unused = tmp47__ >> 3 & 0x1f; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -3355,15 +4530,35 @@ tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tAN switch (pDst->type) { case 0: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.Basic.channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohq(pCtx, &pDst->report.Basic.meas_start_time, pBuf, 0); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->report.Basic.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp48__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3375,84 +4570,209 @@ tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tAN pDst->report.Basic.unused = tmp48__ >> 5 & 0x7; break; case 1: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.CCA.channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohq(pCtx, &pDst->report.CCA.meas_start_time, pBuf, 0); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->report.CCA.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.CCA.cca_busy_fraction = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; break; case 2: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohq(pCtx, &pDst->report.RPIHistogram.meas_start_time, pBuf, 0); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->report.RPIHistogram.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi0_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi1_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi2_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi3_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi4_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi5_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi6_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.RPIHistogram.rpi7_density = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; break; case 5: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.Beacon.regClass = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.Beacon.channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohq(pCtx, &pDst->report.Beacon.meas_start_time, pBuf, 0); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->report.Beacon.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp49__ = *pBuf; pBuf += 1; ielen -= 1; pDst->report.Beacon.condensed_PHY = tmp49__ >> 0 & 0x7f; pDst->report.Beacon.reported_frame_type = tmp49__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.Beacon.RCPI = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.Beacon.RSNI = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->report.Beacon.BSSID, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->report.Beacon.antenna_id = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->report.Beacon.parent_TSF, pBuf, 0); pBuf += 4; ielen -= (tANI_U8)4; @@ -3493,9 +4813,19 @@ tANI_U32 dot11fUnpackIeMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_token = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp50__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3505,60 +4835,140 @@ tANI_U32 dot11fUnpackIeMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA pDst->report = tmp50__ >> 3 & 0x1; pDst->durationMandatory = tmp50__ >> 4 & 0x1; pDst->unused = tmp50__ >> 5 & 0x7; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; switch (pDst->measurement_type) { case 0: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_request.Basic.channel_no = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->measurement_request.Basic.meas_start_time, pBuf, 8); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->measurement_request.Basic.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; break; case 1: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_request.CCA.channel_no = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->measurement_request.CCA.meas_start_time, pBuf, 8); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->measurement_request.CCA.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; break; case 2: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_request.RPIHistogram.channel_no = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->measurement_request.RPIHistogram.meas_start_time, pBuf, 8); pBuf += 8; ielen -= (tANI_U8)8; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->measurement_request.RPIHistogram.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; break; case 5: + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_request.Beacon.regClass = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_request.Beacon.channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->measurement_request.Beacon.randomization, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->measurement_request.Beacon.meas_duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->measurement_request.Beacon.meas_mode = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->measurement_request.Beacon.BSSID, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; @@ -3585,9 +4995,19 @@ tANI_U32 dot11fUnpackIeMobilityDomain(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->MDID, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp51__ = *pBuf; pDst->overDSCap = tmp51__ >> 0 & 0x1; pDst->resourceReqCap = tmp51__ >> 1 & 0x1; @@ -3620,9 +5040,19 @@ tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp52__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3633,6 +5063,11 @@ tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U pDst->QosCap = tmp52__ >> 5 & 0x1; pDst->apsd = tmp52__ >> 6 & 0x1; pDst->rrm = tmp52__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp53__ = *pBuf; pBuf += 1; ielen -= 1; @@ -3640,15 +5075,35 @@ tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U pDst->ImmBA = tmp53__ >> 1 & 0x1; pDst->MobilityDomain = tmp53__ >> 2 & 0x1; pDst->reserved = tmp53__ >> 3 & 0x1f; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->reserved1, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->regulatoryClass = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->PhyType = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -3672,24 +5127,59 @@ tANI_U32 dot11fUnpackIeOBSSScanParameters(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->obssScanPassiveDwell, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->obssScanActiveDwell, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->bssChannelWidthTriggerScanInterval, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->obssScanPassiveTotalPerChannel, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->obssScanActiveTotalPerChannel, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->bssWidthChannelTransitionDelayFactor, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->obssScanActivityThreshold, pBuf, 0); (void)pCtx; return status; @@ -3705,6 +5195,11 @@ tANI_U32 dot11fUnpackIeOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp54__ = *pBuf; pDst->chanWidth = tmp54__ >> 0 & 0x3; pDst->reserved = tmp54__ >> 2 & 0x3; @@ -4136,9 +5631,19 @@ tANI_U32 dot11fUnpackIePTIControl(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->tid = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->sequence_control, pBuf, 0); (void)pCtx; return status; @@ -4154,6 +5659,11 @@ tANI_U32 dot11fUnpackIePUBufferStatus(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp55__ = *pBuf; pDst->ac_bk_traffic_aval = tmp55__ >> 0 & 0x1; pDst->ac_be_traffic_aval = tmp55__ >> 1 & 0x1; @@ -4173,9 +5683,19 @@ tANI_U32 dot11fUnpackIePowerCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->minTxPower = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->maxTxPower = *pBuf; (void)pCtx; return status; @@ -4190,6 +5710,11 @@ tANI_U32 dot11fUnpackIePowerConstraints(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->localPowerConstraints = *pBuf; (void)pCtx; return status; @@ -4204,12 +5729,27 @@ tANI_U32 dot11fUnpackIeQBSSLoad(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->stacount, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->chautil = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->avail, pBuf, 0); (void)pCtx; return status; @@ -4255,6 +5795,11 @@ tANI_U32 dot11fUnpackIeQOSCapsAp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp56__ = *pBuf; pDst->count = tmp56__ >> 0 & 0xf; pDst->qack = tmp56__ >> 4 & 0x1; @@ -4275,6 +5820,11 @@ tANI_U32 dot11fUnpackIeQOSCapsStation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp57__ = *pBuf; pDst->acvo_uapsd = tmp57__ >> 0 & 0x1; pDst->acvi_uapsd = tmp57__ >> 1 & 0x1; @@ -4316,15 +5866,35 @@ tANI_U32 dot11fUnpackIeQuiet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->count = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->period = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->duration, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->offset, pBuf, 0); (void)pCtx; return status; @@ -4339,6 +5909,11 @@ tANI_U32 dot11fUnpackIeRCPIIE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->rcpi = *pBuf; (void)pCtx; return status; @@ -4393,6 +5968,11 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->version, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; @@ -4401,6 +5981,11 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; @@ -4413,10 +5998,20 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->pwise_cipher_suite_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; } + if (unlikely(ielen < pDst->pwise_cipher_suite_count * 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->pwise_cipher_suite_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -4433,10 +6028,20 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; } + if (unlikely(ielen < pDst->akm_suite_count * 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->akm_suite_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -4452,6 +6057,11 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->RSN_Cap, pBuf, 2); pBuf += 2; ielen -= (tANI_U8)2; @@ -4463,10 +6073,20 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->pmkid_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; } + if (unlikely(ielen < pDst->pmkid_count * 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->pmkid_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -4481,6 +6101,11 @@ tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->gp_mgmt_cipher_suite, pBuf, 4); } (void)pCtx; @@ -4496,6 +6121,11 @@ tANI_U32 dot11fUnpackIeRSNIIE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->rsni = *pBuf; (void)pCtx; return status; @@ -4598,12 +6228,27 @@ tANI_U32 dot11fUnpackIeTIM(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->dtim_count = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->dtim_period = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->bmpctl = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -4627,9 +6272,19 @@ tANI_U32 dot11fUnpackIeTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->tx_power = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->link_margin = *pBuf; (void)pCtx; return status; @@ -4657,12 +6312,27 @@ tANI_U32 dot11fUnpackIeTimeAdvertisement(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tAN (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->timing_capabilities = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 10)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->time_value, pBuf, 10); pBuf += 10; ielen -= (tANI_U8)10; + if (unlikely(ielen < 5)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->time_error, pBuf, 5); (void)pCtx; return status; @@ -4677,9 +6347,19 @@ tANI_U32 dot11fUnpackIeTimeoutInterval(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_ (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->timeoutType = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohl(pCtx, &pDst->timeoutValue, pBuf, 0); (void)pCtx; return status; @@ -4694,18 +6374,43 @@ tANI_U32 dot11fUnpackIeVHTExtBssLoad(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->muMIMOCapStaCount = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->ssUnderUtil = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->FortyMHzUtil = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->EightyMHzUtil = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->OneSixtyMHzUtil = *pBuf; (void)pCtx; return status; @@ -4747,6 +6452,11 @@ tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, t (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->version, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; @@ -4755,9 +6465,19 @@ tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, t pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < pDst->akm_suite_count * 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->akm_suite_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -4766,9 +6486,19 @@ tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, t DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, ( pDst->akm_suite_count * 4 ) ); pBuf += ( pDst->akm_suite_count * 4 ); ielen -= ( pDst->akm_suite_count * 4 ); + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->unicast_cipher_suite_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < pDst->unicast_cipher_suite_count * 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->unicast_cipher_suite_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -4777,9 +6507,19 @@ tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, t DOT11F_MEMCPY(pCtx, pDst->unicast_cipher_suites, pBuf, ( pDst->unicast_cipher_suite_count * 4 ) ); pBuf += ( pDst->unicast_cipher_suite_count * 4 ); ielen -= ( pDst->unicast_cipher_suite_count * 4 ); + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->multicast_cipher_suite, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp58__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -4792,10 +6532,20 @@ tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, t } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->bkid_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; } + if (unlikely(ielen < pDst->bkid_count * 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->bkid_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -4835,9 +6585,19 @@ tANI_U32 dot11fUnpackIeWFATPC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->txPower = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->linkMargin = *pBuf; (void)pCtx; return status; @@ -4873,6 +6633,11 @@ tANI_U32 dot11fUnpackIeWMMCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -4881,6 +6646,11 @@ tANI_U32 dot11fUnpackIeWMMCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp59__ = *pBuf; pDst->reserved = tmp59__ >> 0 & 0xf; pDst->qack = tmp59__ >> 4 & 0x1; @@ -4901,9 +6671,19 @@ tANI_U32 dot11fUnpackIeWMMInfoAp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp60__ = *pBuf; pDst->param_set_count = tmp60__ >> 0 & 0xf; pDst->reserved = tmp60__ >> 4 & 0x7; @@ -4922,9 +6702,19 @@ tANI_U32 dot11fUnpackIeWMMInfoStation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp61__ = *pBuf; pDst->acvo_uapsd = tmp61__ >> 0 & 0x1; pDst->acvi_uapsd = tmp61__ >> 1 & 0x1; @@ -4954,6 +6744,11 @@ tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->version = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -4962,12 +6757,27 @@ tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel pDst->present = 0; return ( status | DOT11F_BAD_FIXED_VALUE ); } + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->qosInfo = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->reserved2 = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp62__ = *pBuf; pBuf += 1; ielen -= 1; @@ -4975,14 +6785,29 @@ tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel pDst->acbe_acm = tmp62__ >> 4 & 0x1; pDst->acbe_aci = tmp62__ >> 5 & 0x3; pDst->unused1 = tmp62__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp63__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acbe_acwmin = tmp63__ >> 0 & 0xf; pDst->acbe_acwmax = tmp63__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp64__ = *pBuf; pBuf += 1; ielen -= 1; @@ -4990,14 +6815,29 @@ tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel pDst->acbk_acm = tmp64__ >> 4 & 0x1; pDst->acbk_aci = tmp64__ >> 5 & 0x3; pDst->unused2 = tmp64__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp65__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acbk_acwmin = tmp65__ >> 0 & 0xf; pDst->acbk_acwmax = tmp65__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp66__ = *pBuf; pBuf += 1; ielen -= 1; @@ -5005,14 +6845,29 @@ tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel pDst->acvi_acm = tmp66__ >> 4 & 0x1; pDst->acvi_aci = tmp66__ >> 5 & 0x3; pDst->unused3 = tmp66__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp67__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acvi_acwmin = tmp67__ >> 0 & 0xf; pDst->acvi_acwmax = tmp67__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp68__ = *pBuf; pBuf += 1; ielen -= 1; @@ -5020,11 +6875,21 @@ tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iel pDst->acvo_acm = tmp68__ >> 4 & 0x1; pDst->acvo_aci = tmp68__ >> 5 & 0x3; pDst->unused4 = tmp68__ >> 7 & 0x1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp69__ = *pBuf; pBuf += 1; ielen -= 1; pDst->acvo_acwmin = tmp69__ >> 0 & 0xf; pDst->acvo_acwmax = tmp69__ >> 4 & 0xf; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); (void)pCtx; return status; @@ -5039,6 +6904,11 @@ tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->version, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; @@ -5057,6 +6927,11 @@ tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD else { pDst->multicast_cipher_present = 1U; + if (unlikely(ielen < 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->multicast_cipher, pBuf, 4); pBuf += 4; ielen -= (tANI_U8)4; @@ -5069,10 +6944,20 @@ tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->unicast_cipher_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; } + if (unlikely(ielen < pDst->unicast_cipher_count * 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->unicast_cipher_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -5088,10 +6973,20 @@ tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->auth_suite_count, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; } + if (unlikely(ielen < pDst->auth_suite_count * 4)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + if (pDst->auth_suite_count > 4){ pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; @@ -5106,6 +7001,11 @@ tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tD } else { + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->caps, pBuf, 0); } (void)pCtx; @@ -5378,15 +7278,35 @@ tANI_U32 dot11fUnpackIeext_chan_switch_ann(tpAniSirGlobal pCtx, tANI_U8 *pBuf, t (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->switch_mode = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->new_reg_class = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->new_channel = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->switch_count = *pBuf; (void)pCtx; return status; @@ -5401,6 +7321,11 @@ tANI_U32 dot11fUnpackIefils_assoc_delay_info(tpAniSirGlobal pCtx, tANI_U8 *pBuf, (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->assoc_delay_info = *pBuf; (void)pCtx; return status; @@ -5415,9 +7340,19 @@ tANI_U32 dot11fUnpackIefils_hlp_container(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tA (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->dest_mac, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; + if (unlikely(ielen < 6)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->src_mac, pBuf, 6); pBuf += 6; ielen -= (tANI_U8)6; @@ -5437,6 +7372,11 @@ tANI_U32 dot11fUnpackIefils_indication(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_ (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &tmp70__, pBuf, 0); pBuf += 2; ielen -= 2; @@ -5464,6 +7404,11 @@ tANI_U32 dot11fUnpackIefils_kde(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 iele (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->key_rsc, pBuf, 8); pBuf += 8; ielen -= (tANI_U8)8; @@ -5497,6 +7442,11 @@ tANI_U32 dot11fUnpackIefils_nonce(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 16)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->nonce, pBuf, 16); (void)pCtx; return status; @@ -5511,6 +7461,11 @@ tANI_U32 dot11fUnpackIefils_public_key(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_ (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->key_type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -5529,6 +7484,11 @@ tANI_U32 dot11fUnpackIefils_session(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 8)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + DOT11F_MEMCPY(pCtx, pDst->session, pBuf, 8); (void)pCtx; return status; @@ -5559,6 +7519,11 @@ tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + tmp71__ = *pBuf; pBuf += 1; ielen -= 1; @@ -5575,11 +7540,21 @@ tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 switch (pDst->hs_id_present) { case 1: + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->hs_id.pps_mo.pps_mo_id, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; break; case 2: + if (unlikely(ielen < 2)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + framesntohs(pCtx, &pDst->hs_id.anqp_domain.anqp_domain_id, pBuf, 0); pBuf += 2; ielen -= (tANI_U8)2; @@ -5599,6 +7574,11 @@ tANI_U32 dot11fUnpackIesec_chan_offset_ele(tpAniSirGlobal pCtx, tANI_U8 *pBuf, t (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->secondaryChannelOffset = *pBuf; (void)pCtx; return status; @@ -5623,9 +7603,19 @@ tANI_U32 dot11fUnpackIevendor2_ie(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ie (void) pBuf; (void)ielen; /* Shutup the compiler */ if (pDst->present) status = DOT11F_DUPLICATE_IE; pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + pDst->sub_type = *pBuf; pBuf += 1; ielen -= (tANI_U8)1; @@ -23653,6 +25643,9 @@ tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal pCtx, tmp80__ = 0U; tmp80__ |= ( pSrc->minor << 0 ); tmp80__ |= ( pSrc->major << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp80__; *pnConsumed += 1; pBuf += 1; @@ -24874,6 +26867,9 @@ tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal pCtx, tmp81__ = 0U; tmp81__ |= ( pSrc->minor << 0 ); tmp81__ |= ( pSrc->major << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp81__; *pnConsumed += 1; pBuf += 1; @@ -25029,6 +27025,9 @@ tANI_U32 dot11fPackIeGTK(tpAniSirGlobal pCtx, tmp82__ = 0U; tmp82__ |= ( pSrc->keyId << 0 ); tmp82__ |= ( pSrc->reserved << 2 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp82__, 0); *pnConsumed += 2; pBuf += 2; @@ -25539,6 +27538,9 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, tmp83__ |= ( pSrc->BeaconActive << 5 ); tmp83__ |= ( pSrc->BeaconTable << 6 ); tmp83__ |= ( pSrc->BeaconRepCond << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp83__; *pnConsumed += 1; pBuf += 1; @@ -25552,6 +27554,9 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, tmp84__ |= ( pSrc->LCIAzimuth << 5 ); tmp84__ |= ( pSrc->TCMCapability << 6 ); tmp84__ |= ( pSrc->triggeredTCM << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp84__; *pnConsumed += 1; pBuf += 1; @@ -25561,6 +27566,9 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, tmp85__ |= ( pSrc->RRMMIBEnabled << 1 ); tmp85__ |= ( pSrc->operatingChanMax << 2 ); tmp85__ |= ( pSrc->nonOperatinChanMax << 5 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp85__; *pnConsumed += 1; pBuf += 1; @@ -25572,6 +27580,9 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, tmp86__ |= ( pSrc->RCPIMeasurement << 5 ); tmp86__ |= ( pSrc->RSNIMeasurement << 6 ); tmp86__ |= ( pSrc->BssAvgAccessDelay << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp86__; *pnConsumed += 1; pBuf += 1; @@ -25582,6 +27593,9 @@ tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, tmp87__ |= ( pSrc->fine_time_meas_rpt << 2 ); tmp87__ |= ( pSrc->lci_capability << 3 ); tmp87__ |= ( pSrc->reserved << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp87__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -25679,6 +27693,9 @@ tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal pCtx, tmp88__ |= ( pSrc->tsid << 1 ); tmp88__ |= ( pSrc->direction << 5 ); tmp88__ |= ( pSrc->reserved << 7 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp88__, 0); *pnConsumed += 2; pBuf += 2; @@ -25899,6 +27916,9 @@ tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx, tmp89__ |= ( pSrc->psb << 10 ); tmp89__ |= ( pSrc->user_priority << 11 ); tmp89__ |= ( pSrc->tsinfo_ack_pol << 14 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp89__, 0); *pnConsumed += 2; pBuf += 2; @@ -25906,6 +27926,9 @@ tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx, tmp90__ = 0U; tmp90__ |= ( pSrc->schedule << 0 ); tmp90__ |= ( pSrc->unused << 1 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp90__; *pnConsumed += 1; pBuf += 1; @@ -25913,6 +27936,9 @@ tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx, tmp91__ = 0U; tmp91__ |= ( pSrc->size << 0 ); tmp91__ |= ( pSrc->fixed << 15 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp91__, 0); *pnConsumed += 2; pBuf += 2; @@ -26010,6 +28036,9 @@ tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx, tmp92__ |= ( pSrc->rxAntPattern << 28 ); tmp92__ |= ( pSrc->txAntPattern << 29 ); tmp92__ |= ( pSrc->reserved1 << 30 ); + if (unlikely(nBuf < 4)) + return DOT11F_INCOMPLETE_IE; + frameshtonl(pCtx, pBuf, tmp92__, 0); *pnConsumed += 4; pBuf += 4; @@ -26020,6 +28049,9 @@ tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx, tmp93__ = 0U; tmp93__ |= ( pSrc->rxHighSupDataRate << 0 ); tmp93__ |= ( pSrc->reserved2 << 13 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp93__, 0); *pnConsumed += 2; pBuf += 2; @@ -26030,6 +28062,9 @@ tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx, tmp94__ = 0U; tmp94__ |= ( pSrc->txSupDataRate << 0 ); tmp94__ |= ( pSrc->reserved3 << 13 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp94__, 0); *pnConsumed += 2; // fieldsEndFlag = 1 @@ -26119,6 +28154,9 @@ tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal pCtx, tmp95__ |= ( pSrc->tsid << 1 ); tmp95__ |= ( pSrc->direction << 5 ); tmp95__ |= ( pSrc->reserved << 7 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp95__, 0); *pnConsumed += 2; pBuf += 2; @@ -26391,6 +28429,9 @@ tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx, tmp96__ |= ( pSrc->psb << 10 ); tmp96__ |= ( pSrc->user_priority << 11 ); tmp96__ |= ( pSrc->tsinfo_ack_pol << 14 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp96__, 0); *pnConsumed += 2; pBuf += 2; @@ -26398,6 +28439,9 @@ tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx, tmp97__ = 0U; tmp97__ |= ( pSrc->tsinfo_rsvd << 0 ); tmp97__ |= ( pSrc->burst_size_defn << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp97__; *pnConsumed += 1; pBuf += 1; @@ -26405,6 +28449,9 @@ tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx, tmp98__ = 0U; tmp98__ |= ( pSrc->size << 0 ); tmp98__ |= ( pSrc->fixed << 15 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp98__, 0); *pnConsumed += 2; pBuf += 2; @@ -26802,6 +28849,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp99__ |= ( pSrc->acbe_acm << 4 ); tmp99__ |= ( pSrc->acbe_aci << 5 ); tmp99__ |= ( pSrc->unused1 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp99__; *pnConsumed += 1; pBuf += 1; @@ -26809,6 +28859,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp100__ = 0U; tmp100__ |= ( pSrc->acbe_acwmin << 0 ); tmp100__ |= ( pSrc->acbe_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp100__; *pnConsumed += 1; pBuf += 1; @@ -26821,6 +28874,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp101__ |= ( pSrc->acbk_acm << 4 ); tmp101__ |= ( pSrc->acbk_aci << 5 ); tmp101__ |= ( pSrc->unused2 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp101__; *pnConsumed += 1; pBuf += 1; @@ -26828,6 +28884,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp102__ = 0U; tmp102__ |= ( pSrc->acbk_acwmin << 0 ); tmp102__ |= ( pSrc->acbk_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp102__; *pnConsumed += 1; pBuf += 1; @@ -26840,6 +28899,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp103__ |= ( pSrc->acvi_acm << 4 ); tmp103__ |= ( pSrc->acvi_aci << 5 ); tmp103__ |= ( pSrc->unused3 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp103__; *pnConsumed += 1; pBuf += 1; @@ -26847,6 +28909,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp104__ = 0U; tmp104__ |= ( pSrc->acvi_acwmin << 0 ); tmp104__ |= ( pSrc->acvi_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp104__; *pnConsumed += 1; pBuf += 1; @@ -26859,6 +28924,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp105__ |= ( pSrc->acvo_acm << 4 ); tmp105__ |= ( pSrc->acvo_aci << 5 ); tmp105__ |= ( pSrc->unused4 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp105__; *pnConsumed += 1; pBuf += 1; @@ -26866,6 +28934,9 @@ tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, tmp106__ = 0U; tmp106__ |= ( pSrc->acvo_acwmin << 0 ); tmp106__ |= ( pSrc->acvo_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp106__; *pnConsumed += 1; pBuf += 1; @@ -26906,6 +28977,9 @@ tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal pCtx, tmp107__ |= ( pSrc->use_prot << 1 ); tmp107__ |= ( pSrc->barker_preamble << 2 ); tmp107__ |= ( pSrc->unused << 3 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp107__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -26990,6 +29064,9 @@ tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal pCtx, tmp108__ = 0U; tmp108__ |= ( pSrc->mbssid_mask << 0 ); tmp108__ |= ( pSrc->reserved << 3 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp108__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -27365,6 +29442,9 @@ tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal pCtx, tmp109__ = 0U; tmp109__ |= ( pSrc->reserved << 0 ); tmp109__ |= ( pSrc->IECount << 8 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp109__, 0); *pnConsumed += 2; pBuf += 2; @@ -27420,6 +29500,9 @@ tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx, tmp110__ |= ( pSrc->obssScanExemptionReq << 3 ); tmp110__ |= ( pSrc->obssScanExemptionGrant << 4 ); tmp110__ |= ( pSrc->unused << 5 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp110__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -27504,6 +29587,9 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, tmp111__ |= ( pSrc->psmp << 13 ); tmp111__ |= ( pSrc->stbcControlFrame << 14 ); tmp111__ |= ( pSrc->lsigTXOPProtection << 15 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp111__, 0); *pnConsumed += 2; pBuf += 2; @@ -27512,6 +29598,9 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, tmp112__ |= ( pSrc->maxRxAMPDUFactor << 0 ); tmp112__ |= ( pSrc->mpduDensity << 2 ); tmp112__ |= ( pSrc->reserved1 << 5 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp112__; *pnConsumed += 1; pBuf += 1; @@ -27525,6 +29614,9 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, tmp113__ |= ( pSrc->reserved2 << 3 ); tmp113__ |= ( pSrc->mcsFeedback << 8 ); tmp113__ |= ( pSrc->reserved3 << 10 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp113__, 0); *pnConsumed += 2; pBuf += 2; @@ -27546,6 +29638,9 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, tmp114__ |= ( pSrc->uncompressedSteeringMatrixBFAntennae << 21 ); tmp114__ |= ( pSrc->compressedSteeringMatrixBFAntennae << 23 ); tmp114__ |= ( pSrc->reserved4 << 25 ); + if (unlikely(nBuf < 4)) + return DOT11F_INCOMPLETE_IE; + frameshtonl(pCtx, pBuf, tmp114__, 0); *pnConsumed += 4; pBuf += 4; @@ -27559,6 +29654,9 @@ tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, tmp115__ |= ( pSrc->rxAS << 5 ); tmp115__ |= ( pSrc->txSoundingPPDUs << 6 ); tmp115__ |= ( pSrc->reserved5 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp115__; *pnConsumed += 1; pBuf += 1; @@ -27605,6 +29703,9 @@ tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx, tmp116__ |= ( pSrc->rifsMode << 3 ); tmp116__ |= ( pSrc->controlledAccessOnly << 4 ); tmp116__ |= ( pSrc->serviceIntervalGranularity << 5 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp116__; *pnConsumed += 1; pBuf += 1; @@ -27615,6 +29716,9 @@ tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx, tmp117__ |= ( pSrc->transmitBurstLimit << 3 ); tmp117__ |= ( pSrc->obssNonHTStaPresent << 4 ); tmp117__ |= ( pSrc->reserved << 5 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp117__, 0); *pnConsumed += 2; pBuf += 2; @@ -27627,6 +29731,9 @@ tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx, tmp118__ |= ( pSrc->pcoActive << 10 ); tmp118__ |= ( pSrc->pcoPhase << 11 ); tmp118__ |= ( pSrc->reserved2 << 12 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp118__, 0); *pnConsumed += 2; pBuf += 2; @@ -27743,6 +29850,9 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx, tmp119__ |= ( pSrc->incapable << 1 ); tmp119__ |= ( pSrc->refused << 2 ); tmp119__ |= ( pSrc->unused << 3 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp119__; *pnConsumed += 1; pBuf += 1; @@ -27770,6 +29880,9 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx, tmp120__ |= ( pSrc->report.Basic.rader << 3 ); tmp120__ |= ( pSrc->report.Basic.unmeasured << 4 ); tmp120__ |= ( pSrc->report.Basic.unused << 5 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp120__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -27840,6 +29953,9 @@ tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx, tmp121__ = 0U; tmp121__ |= ( pSrc->report.Beacon.condensed_PHY << 0 ); tmp121__ |= ( pSrc->report.Beacon.reported_frame_type << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp121__; *pnConsumed += 1; pBuf += 1; @@ -27910,6 +30026,9 @@ tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal pCtx, tmp122__ |= ( pSrc->report << 3 ); tmp122__ |= ( pSrc->durationMandatory << 4 ); tmp122__ |= ( pSrc->unused << 5 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp122__; *pnConsumed += 1; pBuf += 1; @@ -28015,6 +30134,9 @@ tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal pCtx, tmp123__ |= ( pSrc->overDSCap << 0 ); tmp123__ |= ( pSrc->resourceReqCap << 1 ); tmp123__ |= ( pSrc->reserved << 2 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp123__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -28061,6 +30183,9 @@ tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal pCtx, tmp124__ |= ( pSrc->QosCap << 5 ); tmp124__ |= ( pSrc->apsd << 6 ); tmp124__ |= ( pSrc->rrm << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp124__; *pnConsumed += 1; pBuf += 1; @@ -28070,6 +30195,9 @@ tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal pCtx, tmp125__ |= ( pSrc->ImmBA << 1 ); tmp125__ |= ( pSrc->MobilityDomain << 2 ); tmp125__ |= ( pSrc->reserved << 3 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp125__; *pnConsumed += 1; pBuf += 1; @@ -28174,6 +30302,9 @@ tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal pCtx, tmp126__ |= ( pSrc->reserved << 2 ); tmp126__ |= ( pSrc->rxNSS << 4 ); tmp126__ |= ( pSrc->rxNSSType << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp126__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -29143,6 +31274,9 @@ tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal pCtx, tmp127__ |= ( pSrc->ac_vi_traffic_aval << 2 ); tmp127__ |= ( pSrc->ac_vo_traffic_aval << 3 ); tmp127__ |= ( pSrc->reserved << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp127__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -29322,6 +31456,9 @@ tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal pCtx, tmp128__ |= ( pSrc->qreq << 5 ); tmp128__ |= ( pSrc->txopreq << 6 ); tmp128__ |= ( pSrc->reserved << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp128__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -29362,6 +31499,9 @@ tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal pCtx, tmp129__ |= ( pSrc->qack << 4 ); tmp129__ |= ( pSrc->max_sp_length << 5 ); tmp129__ |= ( pSrc->more_data_ack << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp129__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -30042,6 +32182,9 @@ tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal pCtx, tmp130__ = 0U; tmp130__ |= ( pSrc->preauth << 0 ); tmp130__ |= ( pSrc->reserved << 1 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp130__, 0); *pnConsumed += 2; pBuf += 2; @@ -30213,6 +32356,9 @@ tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal pCtx, tmp131__ |= ( pSrc->queue_request << 5 ); tmp131__ |= ( pSrc->txop_request << 6 ); tmp131__ |= ( pSrc->more_ack << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp131__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -30262,6 +32408,9 @@ tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal pCtx, tmp132__ |= ( pSrc->param_set_count << 0 ); tmp132__ |= ( pSrc->reserved << 4 ); tmp132__ |= ( pSrc->uapsd << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp132__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -30315,6 +32464,9 @@ tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal pCtx, tmp133__ |= ( pSrc->reserved1 << 4 ); tmp133__ |= ( pSrc->max_sp_length << 5 ); tmp133__ |= ( pSrc->reserved2 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp133__; *pnConsumed += 1; // fieldsEndFlag = 1 @@ -30378,6 +32530,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp134__ |= ( pSrc->acbe_acm << 4 ); tmp134__ |= ( pSrc->acbe_aci << 5 ); tmp134__ |= ( pSrc->unused1 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp134__; *pnConsumed += 1; pBuf += 1; @@ -30385,6 +32540,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp135__ = 0U; tmp135__ |= ( pSrc->acbe_acwmin << 0 ); tmp135__ |= ( pSrc->acbe_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp135__; *pnConsumed += 1; pBuf += 1; @@ -30397,6 +32555,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp136__ |= ( pSrc->acbk_acm << 4 ); tmp136__ |= ( pSrc->acbk_aci << 5 ); tmp136__ |= ( pSrc->unused2 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp136__; *pnConsumed += 1; pBuf += 1; @@ -30404,6 +32565,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp137__ = 0U; tmp137__ |= ( pSrc->acbk_acwmin << 0 ); tmp137__ |= ( pSrc->acbk_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp137__; *pnConsumed += 1; pBuf += 1; @@ -30416,6 +32580,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp138__ |= ( pSrc->acvi_acm << 4 ); tmp138__ |= ( pSrc->acvi_aci << 5 ); tmp138__ |= ( pSrc->unused3 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp138__; *pnConsumed += 1; pBuf += 1; @@ -30423,6 +32590,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp139__ = 0U; tmp139__ |= ( pSrc->acvi_acwmin << 0 ); tmp139__ |= ( pSrc->acvi_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp139__; *pnConsumed += 1; pBuf += 1; @@ -30435,6 +32605,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp140__ |= ( pSrc->acvo_acm << 4 ); tmp140__ |= ( pSrc->acvo_aci << 5 ); tmp140__ |= ( pSrc->unused4 << 7 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp140__; *pnConsumed += 1; pBuf += 1; @@ -30442,6 +32615,9 @@ tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, tmp141__ = 0U; tmp141__ |= ( pSrc->acvo_acwmin << 0 ); tmp141__ |= ( pSrc->acvo_acwmax << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp141__; *pnConsumed += 1; pBuf += 1; @@ -31086,6 +33262,9 @@ tANI_U32 dot11fPackIefils_indication(tpAniSirGlobal pCtx, tmp142__ |= ( pSrc->is_fils_sk_auth_pfs_supported << 10 ); tmp142__ |= ( pSrc->is_pk_auth_supported << 11 ); tmp142__ |= ( pSrc->reserved << 12 ); + if (unlikely(nBuf < 2)) + return DOT11F_INCOMPLETE_IE; + frameshtons(pCtx, pBuf, tmp142__, 0); *pnConsumed += 2; pBuf += 2; @@ -31334,6 +33513,9 @@ tANI_U32 dot11fPackIehs20vendor_ie(tpAniSirGlobal pCtx, tmp143__ |= ( pSrc->hs_id_present << 1 ); tmp143__ |= ( pSrc->reserved << 3 ); tmp143__ |= ( pSrc->release_num << 4 ); + if (unlikely(nBuf < 1)) + return DOT11F_INCOMPLETE_IE; + *pBuf = tmp143__; *pnConsumed += 1; pBuf += 1; |