Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aed0fd4a authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

iwlagn: fix NULL ptr deref when reprogramming sta w/o LQ



Reinette reports a crash in iwl_reprogram_ap_sta(). The
debugging shows:

  b1 16    mov    $0x16,%cl
 *f3 a5    rep movsl %ds     <-- trapping instruction:(%rsi),%es:(%rdi)

which is a memcpy of 22 (0x16) words (movsl). this points
to "priv->stations[sta_id].lq" being NULL since that is
the memcpy() of that size here.

The only way I see for this to happen is if we try to
do some RXON reprogramming while connecting to an AP,
after tx_sync() but before full setup, but that seems
like something that might very well happen.

Fix this by checking if the LQ is present and only then
reprogramming it.

Reported-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent b2ccccdc
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -647,7 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
	int ret;
	struct iwl_addsta_cmd sta_cmd;
	struct iwl_link_quality_cmd lq;
	bool active;
	bool active, have_lq = false;

	spin_lock_irqsave(&priv->shrd->sta_lock, flags);
	if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
@@ -657,7 +657,10 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)

	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
	sta_cmd.mode = 0;
	if (priv->stations[sta_id].lq) {
		memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
		have_lq = true;
	}

	active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
	priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
@@ -679,6 +682,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
	if (ret)
		IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
			priv->stations[sta_id].sta.sta.addr, ret);
	if (have_lq)
		iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
}