qcacld-3.0: Create a new function for adapter reference verification

The current HDD callback in hdd_rx_flush_packet_cbk() does not validate
the adapter context properly. Instead of verifying the adapter magic,
verify the adapter itself is still valid through the adapter list.
Create a new function hdd_get_adapter_by_reference() to verify the
adapter reference.

Change-Id: I468bd55b2318635ad89087e6c6ad6097df68d405
CRs-Fixed: 2563654
This commit is contained in:
Alan Chen 2019-11-12 12:07:02 -08:00 committed by nshrivas
parent 4461014f01
commit dd4e7e3295
3 changed files with 56 additions and 18 deletions

View File

@ -2174,6 +2174,30 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx);
struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
uint32_t vdev_id);
/**
* hdd_adapter_get_by_reference() - Return adapter with the given reference
* @hdd_ctx: hdd context
* @reference: reference for the adapter to get
*
* This function is used to get the adapter with provided reference.
* The adapter reference will be held until being released by calling
* hdd_adapter_put().
*
* Return: adapter pointer if found
*
*/
struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
struct hdd_adapter *reference);
/**
* hdd_adapter_put() - Release reference to adapter
* @adapter: adapter reference
*
* Release reference to adapter previously acquired via
* hdd_adapter_get_*() function
*/
void hdd_adapter_put(struct hdd_adapter *adapter);
struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
tSirMacAddr mac_addr);

View File

@ -7169,6 +7169,26 @@ struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
return NULL;
}
struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
struct hdd_adapter *reference)
{
struct hdd_adapter *adapter;
hdd_for_each_adapter(hdd_ctx, adapter) {
if (adapter == reference) {
dev_hold(adapter->dev);
break;
}
}
return adapter;
}
void hdd_adapter_put(struct hdd_adapter *adapter)
{
dev_put(adapter->dev);
}
struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
const char *iface_name)
{

View File

@ -2018,35 +2018,29 @@ static bool hdd_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb)
QDF_STATUS hdd_rx_flush_packet_cbk(void *adapter_context, uint8_t vdev_id)
{
struct hdd_adapter *adapter = NULL;
struct hdd_context *hdd_ctx = NULL;
struct hdd_adapter *adapter;
struct hdd_context *hdd_ctx;
ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
/* Sanity check on inputs */
if (unlikely(!adapter_context)) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
"%s: Null params being passed", __func__);
return QDF_STATUS_E_FAILURE;
}
adapter = (struct hdd_adapter *)adapter_context;
if (unlikely(adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
"Magic cookie(%x) for adapter sanity verification is invalid",
adapter->magic);
return QDF_STATUS_E_FAILURE;
}
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (unlikely(!hdd_ctx)) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
"%s: HDD context is Null", __func__);
return QDF_STATUS_E_FAILURE;
}
adapter = hdd_adapter_get_by_reference(hdd_ctx, adapter_context);
if (!adapter) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
"%s: Adapter reference is Null", __func__);
return QDF_STATUS_E_FAILURE;
}
if (hdd_ctx->enable_dp_rx_threads)
dp_txrx_flush_pkts_by_vdev_id(soc, vdev_id);
hdd_adapter_put(adapter);
return QDF_STATUS_SUCCESS;
}