iwlwifi: clean key table in iwl_clear_stations_table function

This patch cleans uCode key table bit map iwl_clear_stations_table
since all stations are cleared also the key table must be.

Since the keys are not removed properly on suspend by mac80211
this may result in exhausting key table on resume leading
to memory corruption during removal

This patch also fixes a memory corruption problem reported in
http://marc.info/?l=linux-wireless&m=122641417231586&w=2 and tracked in
http://bugzilla.kernel.org/show_bug.cgi?id=12040.

When the key is removed a second time the offset is set to 255 - this
index is not valid for the ucode_key_table and corrupts the eeprom pointer
(which is 255 bits from ucode_key_table).

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Reported-by: Carlos R. Mafra <crmafra2@gmail.com>
Reported-by: Lukas Hejtmanek <xhejtman@ics.muni.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Tomas Winkler and committed by John W. Linville 40a9a829 f706644d

+24 -3
+3
drivers/net/wireless/iwlwifi/iwl-core.c
··· 290 priv->num_stations = 0; 291 memset(priv->stations, 0, sizeof(priv->stations)); 292 293 spin_unlock_irqrestore(&priv->sta_lock, flags); 294 } 295 EXPORT_SYMBOL(iwl_clear_stations_table);
··· 290 priv->num_stations = 0; 291 memset(priv->stations, 0, sizeof(priv->stations)); 292 293 + /* clean ucode key table bit map */ 294 + priv->ucode_key_table = 0; 295 + 296 spin_unlock_irqrestore(&priv->sta_lock, flags); 297 } 298 EXPORT_SYMBOL(iwl_clear_stations_table);
+21 -3
drivers/net/wireless/iwlwifi/iwl-sta.c
··· 475 if (!test_and_set_bit(i, &priv->ucode_key_table)) 476 return i; 477 478 - return -1; 479 } 480 481 int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) ··· 620 /* else, we are overriding an existing key => no need to allocated room 621 * in uCode. */ 622 623 priv->stations[sta_id].sta.key.key_flags = key_flags; 624 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 625 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; ··· 640 { 641 unsigned long flags; 642 __le16 key_flags = 0; 643 644 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); 645 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); ··· 668 /* else, we are overriding an existing key => no need to allocated room 669 * in uCode. */ 670 671 priv->stations[sta_id].sta.key.key_flags = key_flags; 672 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 673 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 674 675 spin_unlock_irqrestore(&priv->sta_lock, flags); 676 677 - IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); 678 - return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 679 } 680 681 static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, ··· 703 iwl_get_free_ucode_key_index(priv); 704 /* else, we are overriding an existing key => no need to allocated room 705 * in uCode. */ 706 707 /* This copy is acutally not needed: we get the key with each TX */ 708 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); ··· 741 * been replaced by another one with different index. 742 * Don't do anything and return ok 743 */ 744 spin_unlock_irqrestore(&priv->sta_lock, flags); 745 return 0; 746 }
··· 475 if (!test_and_set_bit(i, &priv->ucode_key_table)) 476 return i; 477 478 + return WEP_INVALID_OFFSET; 479 } 480 481 int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) ··· 620 /* else, we are overriding an existing key => no need to allocated room 621 * in uCode. */ 622 623 + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 624 + "no space for new kew"); 625 + 626 priv->stations[sta_id].sta.key.key_flags = key_flags; 627 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 628 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; ··· 637 { 638 unsigned long flags; 639 __le16 key_flags = 0; 640 + int ret; 641 642 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); 643 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); ··· 664 /* else, we are overriding an existing key => no need to allocated room 665 * in uCode. */ 666 667 + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 668 + "no space for new kew"); 669 + 670 priv->stations[sta_id].sta.key.key_flags = key_flags; 671 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 672 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 673 674 + ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 675 + 676 spin_unlock_irqrestore(&priv->sta_lock, flags); 677 678 + return ret; 679 } 680 681 static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, ··· 695 iwl_get_free_ucode_key_index(priv); 696 /* else, we are overriding an existing key => no need to allocated room 697 * in uCode. */ 698 + 699 + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 700 + "no space for new kew"); 701 702 /* This copy is acutally not needed: we get the key with each TX */ 703 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); ··· 730 * been replaced by another one with different index. 731 * Don't do anything and return ok 732 */ 733 + spin_unlock_irqrestore(&priv->sta_lock, flags); 734 + return 0; 735 + } 736 + 737 + if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { 738 + IWL_WARNING("Removing wrong key %d 0x%x\n", 739 + keyconf->keyidx, key_flags); 740 spin_unlock_irqrestore(&priv->sta_lock, flags); 741 return 0; 742 }