diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/key.c | 32 | ||||
-rw-r--r-- | net/mac80211/key.h | 11 |
3 files changed, 25 insertions, 22 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 61fc9116380d..c2d4bf24a8c2 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, * add it to the device after the station. */ if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { - ieee80211_key_free(sdata->local, key); + ieee80211_key_free_unused(key); err = -ENOENT; goto out_unlock; } @@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, } err = ieee80211_key_link(key, sdata, sta); - if (err) - ieee80211_key_free(sdata->local, key); out_unlock: mutex_unlock(&sdata->local->sta_mtx); diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 99e9f6ae6a54..d86be6466724 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -397,6 +397,15 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, return key; } +static void ieee80211_key_free_common(struct ieee80211_key *key) +{ + if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) + ieee80211_aes_key_free(key->u.ccmp.tfm); + if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) + ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); + kfree(key); +} + static void __ieee80211_key_destroy(struct ieee80211_key *key, bool delay_tailroom) { @@ -412,10 +421,6 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key, if (key->local) ieee80211_key_disable_hw_accel(key); - if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) - ieee80211_aes_key_free(key->u.ccmp.tfm); - if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) - ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); if (key->local) { struct ieee80211_sub_if_data *sdata = key->sdata; @@ -431,7 +436,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key, } } - kfree(key); + ieee80211_key_free_common(key); +} + +void ieee80211_key_free_unused(struct ieee80211_key *key) +{ + WARN_ON(key->sdata || key->local); + ieee80211_key_free_common(key); } int ieee80211_key_link(struct ieee80211_key *key, @@ -469,6 +480,9 @@ int ieee80211_key_link(struct ieee80211_key *key, ret = ieee80211_key_enable_hw_accel(key); + if (ret) + __ieee80211_key_free(key, true); + mutex_unlock(&sdata->local->key_mtx); return ret; @@ -489,14 +503,6 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) __ieee80211_key_destroy(key, delay_tailroom); } -void ieee80211_key_free(struct ieee80211_local *local, - struct ieee80211_key *key) -{ - mutex_lock(&local->key_mtx); - __ieee80211_key_free(key, true); - mutex_unlock(&local->key_mtx); -} - void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) { struct ieee80211_key *key; diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 2a682d81cee9..8ef56cdfe3d7 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -129,14 +129,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, size_t seq_len, const u8 *seq); /* * Insert a key into data structures (sdata, sta if necessary) - * to make it used, free old key. + * to make it used, free old key. On failure, also free the new key. */ -int __must_check ieee80211_key_link(struct ieee80211_key *key, - struct ieee80211_sub_if_data *sdata, - struct sta_info *sta); +int ieee80211_key_link(struct ieee80211_key *key, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta); void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); -void ieee80211_key_free(struct ieee80211_local *local, - struct ieee80211_key *key); +void ieee80211_key_free_unused(struct ieee80211_key *key); void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, bool uni, bool multi); void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, |