Unverified Commit 68b0fb4e authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13854 CVE-2024-53059

Merge Pull Request from: @ci-robot 
 
PR sync from: Liu Jian <liujian56@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/JKAO5KVWX5TZUD3IVH6NHV7CA4NSJB2X/ 
CVE-2024-53059

Daniel Gabay (1):
  wifi: iwlwifi: mvm: Fix response handling in
    iwl_mvm_send_recovery_cmd()

Emmanuel Grumbach (1):
  wifi: iwlwifi: mvm: disconnect station vifs if recovery failed

Johannes Berg (2):
  mac80211: do drv_reconfig_complete() before restarting all
  mac80211: always have ieee80211_sta_restart()

Youghandhar Chintala (1):
  mac80211: Add support to trigger sta disconnect on hardware restart


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IB5KQF 
 
Link:https://gitee.com/openeuler/kernel/pulls/13854

 

Reviewed-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents 6285e577 1ef7cbe1
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -1251,11 +1251,18 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
}
#endif /* CONFIG_ACPI */

static void iwl_mvm_disconnect_iterator(void *data, u8 *mac,
					struct ieee80211_vif *vif)
{
	if (vif->type == NL80211_IFTYPE_STATION)
		ieee80211_hw_restart_disconnect(vif);
}

void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
{
	u32 error_log_size = mvm->fw->ucode_capa.error_log_size;
	u32 status = 0;
	int ret;
	u32 resp;

	struct iwl_fw_error_recovery_cmd recovery_cmd = {
		.flags = cpu_to_le32(flags),
@@ -1263,7 +1270,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
	};
	struct iwl_host_cmd host_cmd = {
		.id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD),
		.flags = CMD_WANT_SKB,
		.data = {&recovery_cmd, },
		.len = {sizeof(recovery_cmd), },
	};
@@ -1283,7 +1289,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
		recovery_cmd.buf_size = cpu_to_le32(error_log_size);
	}

	ret = iwl_mvm_send_cmd(mvm, &host_cmd);
	ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);
	kfree(mvm->error_recovery_buf);
	mvm->error_recovery_buf = NULL;

@@ -1294,11 +1300,15 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)

	/* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */
	if (flags & ERROR_RECOVERY_UPDATE_DB) {
		resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data);
		if (resp)
		if (status) {
			IWL_ERR(mvm,
				"Failed to send recovery cmd blob was invalid %d\n",
				resp);
				status);

			ieee80211_iterate_interfaces(mvm->hw, 0,
						     iwl_mvm_disconnect_iterator,
						     mvm);
		}
	}
}

+10 −0
Original line number Diff line number Diff line
@@ -5899,6 +5899,16 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif);
 */
void ieee80211_resume_disconnect(struct ieee80211_vif *vif);

/**
 * ieee80211_hw_restart_disconnect - disconnect from AP after
 * hardware restart
 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
 *
 * Instructs mac80211 to disconnect from the AP after
 * hardware restart.
 */
void ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif);

/**
 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring
 *	rssi threshold triggered
+3 −0
Original line number Diff line number Diff line
@@ -762,6 +762,8 @@ struct ieee80211_if_mesh {
 *	back to wireless media and to the local net stack.
 * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume.
 * @IEEE80211_SDATA_IN_DRIVER: indicates interface was added to driver
 * @IEEE80211_SDATA_DISCONNECT_HW_RESTART: Disconnect after hardware restart
 *  recovery
 */
enum ieee80211_sub_if_data_flags {
	IEEE80211_SDATA_ALLMULTI		= BIT(0),
@@ -769,6 +771,7 @@ enum ieee80211_sub_if_data_flags {
	IEEE80211_SDATA_DONT_BRIDGE_PACKETS	= BIT(3),
	IEEE80211_SDATA_DISCONNECT_RESUME	= BIT(4),
	IEEE80211_SDATA_IN_DRIVER		= BIT(5),
	IEEE80211_SDATA_DISCONNECT_HW_RESTART	= BIT(6),
};

/**
+13 −1
Original line number Diff line number Diff line
@@ -4778,6 +4778,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)

	sdata_unlock(sdata);
}
#endif

void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
{
@@ -4799,9 +4800,20 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
		sdata_unlock(sdata);
		return;
	}

	if (sdata->flags & IEEE80211_SDATA_DISCONNECT_HW_RESTART) {
		sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_HW_RESTART;
		mlme_dbg(sdata, "driver requested disconnect after hardware restart\n");
		ieee80211_sta_connection_lost(sdata,
					      ifmgd->associated->bssid,
					      WLAN_REASON_UNSPECIFIED,
					      true);
		sdata_unlock(sdata);
		return;
	}

	sdata_unlock(sdata);
}
#endif

/* interface setup */
void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
+36 −9
Original line number Diff line number Diff line
@@ -2290,6 +2290,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
	struct cfg80211_sched_scan_request *sched_scan_req;
	bool sched_scan_stopped = false;
	bool suspended = local->suspended;
	bool in_reconfig = false;

	/* nothing to do if HW shouldn't run */
	if (!local->open_count)
@@ -2632,7 +2633,15 @@ int ieee80211_reconfig(struct ieee80211_local *local)
		mutex_unlock(&local->sta_mtx);
	}

	/*
	 * If this is for hw restart things are still running.
	 * We may want to change that later, however.
	 */
	if (local->open_count && (!suspended || reconfig_due_to_wowlan))
		drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);

	if (local->in_reconfig) {
		in_reconfig = local->in_reconfig;
		local->in_reconfig = false;
		barrier();

@@ -2650,12 +2659,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
					IEEE80211_QUEUE_STOP_REASON_SUSPEND,
					false);

	/*
	 * If this is for hw restart things are still running.
	 * We may want to change that later, however.
	 */
	if (local->open_count && (!suspended || reconfig_due_to_wowlan))
		drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
	if (in_reconfig) {
		list_for_each_entry(sdata, &local->interfaces, list) {
			if (!ieee80211_sdata_running(sdata))
				continue;
			if (sdata->vif.type == NL80211_IFTYPE_STATION)
				ieee80211_sta_restart(sdata);
		}
	}

	if (!suspended)
		return 0;
@@ -2686,7 +2697,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
	return 0;
}

void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
static void ieee80211_reconfig_disconnect(struct ieee80211_vif *vif, u8 flag)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_local *local;
@@ -2698,19 +2709,35 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
	sdata = vif_to_sdata(vif);
	local = sdata->local;

	if (WARN_ON(!local->resuming))
	if (WARN_ON(flag & IEEE80211_SDATA_DISCONNECT_RESUME &&
		    !local->resuming))
		return;

	if (WARN_ON(flag & IEEE80211_SDATA_DISCONNECT_HW_RESTART &&
		    !local->in_reconfig))
		return;

	if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
		return;

	sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME;
	sdata->flags |= flag;

	mutex_lock(&local->key_mtx);
	list_for_each_entry(key, &sdata->key_list, list)
		key->flags |= KEY_FLAG_TAINTED;
	mutex_unlock(&local->key_mtx);
}

void ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif)
{
	ieee80211_reconfig_disconnect(vif, IEEE80211_SDATA_DISCONNECT_HW_RESTART);
}
EXPORT_SYMBOL_GPL(ieee80211_hw_restart_disconnect);

void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
{
	ieee80211_reconfig_disconnect(vif, IEEE80211_SDATA_DISCONNECT_RESUME);
}
EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);

void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)