mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-10 06:34:17 +08:00
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: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
b2ccccdca4
commit
aed0fd4acd
@ -647,7 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
|||||||
int ret;
|
int ret;
|
||||||
struct iwl_addsta_cmd sta_cmd;
|
struct iwl_addsta_cmd sta_cmd;
|
||||||
struct iwl_link_quality_cmd lq;
|
struct iwl_link_quality_cmd lq;
|
||||||
bool active;
|
bool active, have_lq = false;
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->shrd->sta_lock, flags);
|
spin_lock_irqsave(&priv->shrd->sta_lock, flags);
|
||||||
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
|
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));
|
memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
|
||||||
sta_cmd.mode = 0;
|
sta_cmd.mode = 0;
|
||||||
memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
|
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;
|
active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
|
||||||
priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
|
priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
|
||||||
@ -679,7 +682,8 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
|||||||
if (ret)
|
if (ret)
|
||||||
IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
|
IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
|
||||||
priv->stations[sta_id].sta.sta.addr, ret);
|
priv->stations[sta_id].sta.sta.addr, ret);
|
||||||
iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
|
if (have_lq)
|
||||||
|
iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
|
int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
|
||||||
|
Loading…
Reference in New Issue
Block a user