Unverified Commit 6fa0bb19 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6399 wifi: wilc1000: prevent use-after-free on vif when cleaning up all interfaces

parents 79fe680b c5a73a12
Loading
Loading
Loading
Loading
+7 −21
Original line number Diff line number Diff line
@@ -821,8 +821,7 @@ static const struct net_device_ops wilc_netdev_ops = {

void wilc_netdev_cleanup(struct wilc *wilc)
{
	struct wilc_vif *vif;
	int srcu_idx, ifc_cnt = 0;
	struct wilc_vif *vif, *vif_tmp;

	if (!wilc)
		return;
@@ -832,33 +831,20 @@ void wilc_netdev_cleanup(struct wilc *wilc)
		wilc->firmware = NULL;
	}

	srcu_idx = srcu_read_lock(&wilc->srcu);
	list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
	list_for_each_entry_safe(vif, vif_tmp, &wilc->vif_list, list) {
		mutex_lock(&wilc->vif_mutex);
		list_del_rcu(&vif->list);
		wilc->vif_num--;
		mutex_unlock(&wilc->vif_mutex);
		synchronize_srcu(&wilc->srcu);
		if (vif->ndev)
			unregister_netdev(vif->ndev);
	}
	srcu_read_unlock(&wilc->srcu, srcu_idx);

	wilc_wfi_deinit_mon_interface(wilc, false);
	flush_workqueue(wilc->hif_workqueue);
	destroy_workqueue(wilc->hif_workqueue);

	while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) {
		mutex_lock(&wilc->vif_mutex);
		if (wilc->vif_num <= 0) {
			mutex_unlock(&wilc->vif_mutex);
			break;
		}
		vif = wilc_get_wl_to_vif(wilc);
		if (!IS_ERR(vif))
			list_del_rcu(&vif->list);

		wilc->vif_num--;
		mutex_unlock(&wilc->vif_mutex);
		synchronize_srcu(&wilc->srcu);
		ifc_cnt++;
	}

	wilc_wlan_cfg_deinit(wilc);
	wlan_deinit_locks(wilc);
	kfree(wilc->bus_data);