diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-07-06 15:59:39 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-08 11:11:19 -0400 |
commit | aba83a0b301c32dbb91c017f33307611e1a1d384 (patch) | |
tree | 9f8478ddf2160c9b4c50666e037e6239ea52e274 /net/mac80211/debugfs_key.c | |
parent | 523b02ea23b175dd3e46e3daf1bc9354376640a3 (diff) |
mac80211: fix CCMP races
Since we can process multiple packets at the
same time for different ACs, but the PN is
allocated from a single counter, we need to
use an atomic value there. Use atomic64_t to
make this cheaper on 64-bit platforms, other
platforms will support this through software
emulation, see lib/atomic64.c.
We also need to use an on-stack scratch buf
so that multiple packets won't corrupt each
others scratch buffers.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/debugfs_key.c')
-rw-r--r-- | net/mac80211/debugfs_key.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 33c58b85c911..4433760db4c7 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -79,6 +79,7 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | |||
79 | size_t count, loff_t *ppos) | 79 | size_t count, loff_t *ppos) |
80 | { | 80 | { |
81 | const u8 *tpn; | 81 | const u8 *tpn; |
82 | u64 pn; | ||
82 | char buf[20]; | 83 | char buf[20]; |
83 | int len; | 84 | int len; |
84 | struct ieee80211_key *key = file->private_data; | 85 | struct ieee80211_key *key = file->private_data; |
@@ -94,9 +95,10 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | |||
94 | key->u.tkip.tx.iv16); | 95 | key->u.tkip.tx.iv16); |
95 | break; | 96 | break; |
96 | case WLAN_CIPHER_SUITE_CCMP: | 97 | case WLAN_CIPHER_SUITE_CCMP: |
97 | tpn = key->u.ccmp.tx_pn; | 98 | pn = atomic64_read(&key->u.ccmp.tx_pn); |
98 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", | 99 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", |
99 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); | 100 | (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), |
101 | (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); | ||
100 | break; | 102 | break; |
101 | case WLAN_CIPHER_SUITE_AES_CMAC: | 103 | case WLAN_CIPHER_SUITE_AES_CMAC: |
102 | tpn = key->u.aes_cmac.tx_pn; | 104 | tpn = key->u.aes_cmac.tx_pn; |