diff options
Diffstat (limited to 'net/mac80211/ieee80211_ioctl.c')
-rw-r--r-- | net/mac80211/ieee80211_ioctl.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 41130b303170..a611c8bc76bd 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c | |||
@@ -36,6 +36,7 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
36 | struct sta_info *sta; | 36 | struct sta_info *sta; |
37 | struct ieee80211_key *key; | 37 | struct ieee80211_key *key; |
38 | struct ieee80211_sub_if_data *sdata; | 38 | struct ieee80211_sub_if_data *sdata; |
39 | int err; | ||
39 | 40 | ||
40 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 41 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
41 | 42 | ||
@@ -46,23 +47,31 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
46 | } | 47 | } |
47 | 48 | ||
48 | if (remove) { | 49 | if (remove) { |
50 | rcu_read_lock(); | ||
51 | |||
52 | err = 0; | ||
53 | |||
49 | if (is_broadcast_ether_addr(sta_addr)) { | 54 | if (is_broadcast_ether_addr(sta_addr)) { |
50 | key = sdata->keys[idx]; | 55 | key = sdata->keys[idx]; |
51 | } else { | 56 | } else { |
52 | sta = sta_info_get(local, sta_addr); | 57 | sta = sta_info_get(local, sta_addr); |
53 | if (!sta) | 58 | if (!sta) { |
54 | return -ENOENT; | 59 | err = -ENOENT; |
60 | goto out_unlock; | ||
61 | } | ||
55 | key = sta->key; | 62 | key = sta->key; |
56 | } | 63 | } |
57 | 64 | ||
58 | ieee80211_key_free(key); | 65 | ieee80211_key_free(key); |
59 | return 0; | ||
60 | } else { | 66 | } else { |
61 | key = ieee80211_key_alloc(alg, idx, key_len, _key); | 67 | key = ieee80211_key_alloc(alg, idx, key_len, _key); |
62 | if (!key) | 68 | if (!key) |
63 | return -ENOMEM; | 69 | return -ENOMEM; |
64 | 70 | ||
65 | sta = NULL; | 71 | sta = NULL; |
72 | err = 0; | ||
73 | |||
74 | rcu_read_lock(); | ||
66 | 75 | ||
67 | if (!is_broadcast_ether_addr(sta_addr)) { | 76 | if (!is_broadcast_ether_addr(sta_addr)) { |
68 | set_tx_key = 0; | 77 | set_tx_key = 0; |
@@ -74,13 +83,15 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
74 | */ | 83 | */ |
75 | if (idx != 0 && alg != ALG_WEP) { | 84 | if (idx != 0 && alg != ALG_WEP) { |
76 | ieee80211_key_free(key); | 85 | ieee80211_key_free(key); |
77 | return -EINVAL; | 86 | err = -EINVAL; |
87 | goto out_unlock; | ||
78 | } | 88 | } |
79 | 89 | ||
80 | sta = sta_info_get(local, sta_addr); | 90 | sta = sta_info_get(local, sta_addr); |
81 | if (!sta) { | 91 | if (!sta) { |
82 | ieee80211_key_free(key); | 92 | ieee80211_key_free(key); |
83 | return -ENOENT; | 93 | err = -ENOENT; |
94 | goto out_unlock; | ||
84 | } | 95 | } |
85 | } | 96 | } |
86 | 97 | ||
@@ -90,7 +101,10 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
90 | ieee80211_set_default_key(sdata, idx); | 101 | ieee80211_set_default_key(sdata, idx); |
91 | } | 102 | } |
92 | 103 | ||
93 | return 0; | 104 | out_unlock: |
105 | rcu_read_unlock(); | ||
106 | |||
107 | return err; | ||
94 | } | 108 | } |
95 | 109 | ||
96 | static int ieee80211_ioctl_siwgenie(struct net_device *dev, | 110 | static int ieee80211_ioctl_siwgenie(struct net_device *dev, |