aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-06-11 21:47:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-14 12:18:08 -0400
commit4564ce8b0e17d91d047aa875843deb2cccf3f268 (patch)
tree46fe73e2085af1e9b62e787014128536f9424529
parent630fe9b6f774dd55b71fe94392101eb00df58762 (diff)
iwlwifi: add bad length check for WEP keys
This patch adds a check for bad length in set key flow. This solves the Oops reported by Thomas Backlund, Joonwoo Park and Ian Schram. It also adds some debug printing that can be useful. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c18
2 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index a093f5b83cb6..b58f79626e10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1002,6 +1002,7 @@ struct iwl_wep_cmd {
1002#define WEP_KEY_WEP_TYPE 1 1002#define WEP_KEY_WEP_TYPE 1
1003#define WEP_KEYS_MAX 4 1003#define WEP_KEYS_MAX 4
1004#define WEP_INVALID_OFFSET 0xff 1004#define WEP_INVALID_OFFSET 0xff
1005#define WEP_KEY_LEN_64 5
1005#define WEP_KEY_LEN_128 13 1006#define WEP_KEY_LEN_128 13
1006 1007
1007/****************************************************************************** 1008/******************************************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index b3caed487f03..3e257cfb44a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -488,6 +488,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
488 priv->default_wep_key--; 488 priv->default_wep_key--;
489 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); 489 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
490 ret = iwl_send_static_wepkey_cmd(priv, 1); 490 ret = iwl_send_static_wepkey_cmd(priv, 1);
491 IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
492 keyconf->keyidx, ret);
491 spin_unlock_irqrestore(&priv->sta_lock, flags); 493 spin_unlock_irqrestore(&priv->sta_lock, flags);
492 494
493 return ret; 495 return ret;
@@ -500,6 +502,12 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
500 int ret; 502 int ret;
501 unsigned long flags; 503 unsigned long flags;
502 504
505 if (keyconf->keylen != WEP_KEY_LEN_128 &&
506 keyconf->keylen != WEP_KEY_LEN_64) {
507 IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
508 return -EINVAL;
509 }
510
503 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; 511 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
504 keyconf->hw_key_idx = HW_KEY_DEFAULT; 512 keyconf->hw_key_idx = HW_KEY_DEFAULT;
505 priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; 513 priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
@@ -516,6 +524,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
516 keyconf->keylen); 524 keyconf->keylen);
517 525
518 ret = iwl_send_static_wepkey_cmd(priv, 0); 526 ret = iwl_send_static_wepkey_cmd(priv, 0);
527 IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
528 keyconf->keylen, keyconf->keyidx, ret);
519 spin_unlock_irqrestore(&priv->sta_lock, flags); 529 spin_unlock_irqrestore(&priv->sta_lock, flags);
520 530
521 return ret; 531 return ret;
@@ -662,6 +672,9 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
662 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); 672 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
663 keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; 673 keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
664 674
675 IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
676 keyconf->keyidx, sta_id);
677
665 if (keyconf->keyidx != keyidx) { 678 if (keyconf->keyidx != keyidx) {
666 /* We need to remove a key with index different that the one 679 /* We need to remove a key with index different that the one
667 * in the uCode. This means that the key we need to remove has 680 * in the uCode. This means that the key we need to remove has
@@ -686,7 +699,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
686 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 699 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
687 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 700 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
688 701
689 IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
690 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 702 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
691 spin_unlock_irqrestore(&priv->sta_lock, flags); 703 spin_unlock_irqrestore(&priv->sta_lock, flags);
692 return ret; 704 return ret;
@@ -716,6 +728,10 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
716 ret = -EINVAL; 728 ret = -EINVAL;
717 } 729 }
718 730
731 IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
732 keyconf->alg, keyconf->keylen, keyconf->keyidx,
733 sta_id, ret);
734
719 return ret; 735 return ret;
720} 736}
721EXPORT_SYMBOL(iwl_set_dynamic_key); 737EXPORT_SYMBOL(iwl_set_dynamic_key);