aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-10 09:55:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-11 12:32:52 -0500
commitaed0fd4acd9b1a4fa042ea65f5de697996f6ac7f (patch)
tree120fd648461bbfd8e771e5952d169cecd75a1f71 /drivers
parentb2ccccdca46273c7b321ecf5041c362cd950da20 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 93067686218..1b112dfbce7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -647,7 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
647 int ret; 647 int ret;
648 struct iwl_addsta_cmd sta_cmd; 648 struct iwl_addsta_cmd sta_cmd;
649 struct iwl_link_quality_cmd lq; 649 struct iwl_link_quality_cmd lq;
650 bool active; 650 bool active, have_lq = false;
651 651
652 spin_lock_irqsave(&priv->shrd->sta_lock, flags); 652 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
653 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 653 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)
657 657
658 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); 658 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
659 sta_cmd.mode = 0; 659 sta_cmd.mode = 0;
660 memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); 660 if (priv->stations[sta_id].lq) {
661 memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
662 have_lq = true;
663 }
661 664
662 active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; 665 active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
663 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 666 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)
679 if (ret) 682 if (ret)
680 IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", 683 IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
681 priv->stations[sta_id].sta.sta.addr, ret); 684 priv->stations[sta_id].sta.sta.addr, ret);
682 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); 685 if (have_lq)
686 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
683} 687}
684 688
685int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) 689int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)