aboutsummaryrefslogtreecommitdiff
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-07-06 21:59:39 +0200
committerJohn W. Linville <linville@tuxdriver.com>2011-07-08 11:11:19 -0400
commitaba83a0b301c32dbb91c017f33307611e1a1d384 (patch)
tree9f8478ddf2160c9b4c50666e037e6239ea52e274 /net/mac80211/cfg.c
parent523b02ea23b175dd3e46e3daf1bc9354376640a3 (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/cfg.c')
-rw-r--r--net/mac80211/cfg.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 295ab747663..3000b4c3b52 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -209,6 +209,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
u8 seq[6] = {0};
struct key_params params;
struct ieee80211_key *key = NULL;
+ u64 pn64;
u32 iv32;
u16 iv16;
int err = -ENOENT;
@@ -256,12 +257,13 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
params.seq_len = 6;
break;
case WLAN_CIPHER_SUITE_CCMP:
- seq[0] = key->u.ccmp.tx_pn[5];
- seq[1] = key->u.ccmp.tx_pn[4];
- seq[2] = key->u.ccmp.tx_pn[3];
- seq[3] = key->u.ccmp.tx_pn[2];
- seq[4] = key->u.ccmp.tx_pn[1];
- seq[5] = key->u.ccmp.tx_pn[0];
+ pn64 = atomic64_read(&key->u.ccmp.tx_pn);
+ seq[0] = pn64;
+ seq[1] = pn64 >> 8;
+ seq[2] = pn64 >> 16;
+ seq[3] = pn64 >> 24;
+ seq[4] = pn64 >> 32;
+ seq[5] = pn64 >> 40;
params.seq = seq;
params.seq_len = 6;
break;