qcacld-3.0: Cancel iface_idle_work before wma_wmi_stop
When interface change timer expires, wma_wmi_service_close() is called from hdd_iface_change_callback()->hdd_wlan_stop_modules() ->cds_close(). wmi_handle is made null here. At the same time, if there is a modem reboot, host will receive early indication from FW. Due to this, icnss driver sent ICNSS_UEVENT_FW_DOWN event to host and it calls wmi_stop() again from icnss_call_driver_uevent()->pld_snoc_uevent()-> wlan_hdd_pld_uevent() -> wlan_hdd_set_the_pld_uevent()-> wma_wmi_stop() -> wmi_stop(). As wmi_handle which was marked null during wlan stop modules, this causes potential NULL pointer dereference. Flush iface_idle_work before wma_wmi_stop and add NULL check before accessing wmi_handle. Change-Id: I1bfa8ab7329040c0b5ba989c0d7de7bf7228dd35 CRs-Fixed: 2328575
Cette révision appartient à :

révisé par
nshrivas

Parent
d2639bd16e
révision
bc5a34bba2
@@ -1484,8 +1484,6 @@ static void wlan_hdd_purge_notifier(void)
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
|
||||
|
||||
mutex_lock(&hdd_ctx->iface_change_lock);
|
||||
cds_shutdown_notifier_call();
|
||||
cds_shutdown_notifier_purge();
|
||||
@@ -1561,6 +1559,25 @@ static void wlan_hdd_handle_the_pld_uevent(struct pld_uevent_data *uevent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_flush_iface_idle_work() - function to flush the interface idle work
|
||||
* event
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void wlan_hdd_flush_iface_idle_work(void)
|
||||
{
|
||||
struct hdd_context *hdd_ctx;
|
||||
|
||||
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
|
||||
if (!hdd_ctx) {
|
||||
hdd_err("hdd context is NULL ");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_pld_uevent() - update driver status
|
||||
* @dev: device
|
||||
@@ -1574,7 +1591,9 @@ static void wlan_hdd_pld_uevent(struct device *dev,
|
||||
hdd_enter();
|
||||
hdd_info("pld event %d", uevent->uevent);
|
||||
|
||||
wlan_hdd_flush_iface_idle_work();
|
||||
wma_wmi_stop();
|
||||
|
||||
wlan_hdd_set_the_pld_uevent(uevent);
|
||||
mutex_lock(&hdd_init_deinit_lock);
|
||||
wlan_hdd_handle_the_pld_uevent(uevent);
|
||||
|
@@ -3044,9 +3044,9 @@ void wma_wmi_stop(void)
|
||||
tp_wma_handle wma_handle;
|
||||
|
||||
wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
|
||||
if (wma_handle == NULL) {
|
||||
if ((!wma_handle) || (!wma_handle->wmi_handle)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
|
||||
"wma_handle is NULL\n");
|
||||
"wma_handle or wmi_handle is NULL\n");
|
||||
return;
|
||||
}
|
||||
wmi_stop(wma_handle->wmi_handle);
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur