mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
wifi: mac80211: fix potential key leak
When returning from ieee80211_key_link(), the key needs to have been freed or successfully installed. This was missed in a number of error paths, fix it. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
31db78a492
commit
d097ae01eb
1 changed files with 15 additions and 5 deletions
|
@ -802,6 +802,9 @@ static void ieee80211_key_destroy(struct ieee80211_key *key,
|
|||
|
||||
void ieee80211_key_free_unused(struct ieee80211_key *key)
|
||||
{
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
WARN_ON(key->sdata || key->local);
|
||||
ieee80211_key_free_common(key);
|
||||
}
|
||||
|
@ -854,7 +857,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
|||
* can cause warnings to appear.
|
||||
*/
|
||||
bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION;
|
||||
int ret = -EOPNOTSUPP;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&sdata->local->key_mtx);
|
||||
|
||||
|
@ -868,8 +871,10 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
|||
* the same cipher. Enforce the assumption for pairwise keys.
|
||||
*/
|
||||
if ((alt_key && alt_key->conf.cipher != key->conf.cipher) ||
|
||||
(old_key && old_key->conf.cipher != key->conf.cipher))
|
||||
(old_key && old_key->conf.cipher != key->conf.cipher)) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
} else if (sta) {
|
||||
struct link_sta_info *link_sta = &sta->deflink;
|
||||
int link_id = key->conf.link_id;
|
||||
|
@ -895,8 +900,10 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
|||
|
||||
/* Non-pairwise keys must also not switch the cipher on rekey */
|
||||
if (!pairwise) {
|
||||
if (old_key && old_key->conf.cipher != key->conf.cipher)
|
||||
if (old_key && old_key->conf.cipher != key->conf.cipher) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -904,9 +911,8 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
|||
* new version of the key to avoid nonce reuse or replay issues.
|
||||
*/
|
||||
if (ieee80211_key_identical(sdata, old_key, key)) {
|
||||
ieee80211_key_free_unused(key);
|
||||
ret = -EALREADY;
|
||||
goto out;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
key->local = sdata->local;
|
||||
|
@ -930,7 +936,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
|||
ieee80211_key_free(key, delay_tailroom);
|
||||
}
|
||||
|
||||
key = NULL;
|
||||
|
||||
out:
|
||||
ieee80211_key_free_unused(key);
|
||||
unlock:
|
||||
mutex_unlock(&sdata->local->key_mtx);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue