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