Commit d097ae01 authored by Johannes Berg's avatar Johannes Berg

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 31db78a4
...@@ -802,6 +802,9 @@ static void ieee80211_key_destroy(struct ieee80211_key *key, ...@@ -802,6 +802,9 @@ static void ieee80211_key_destroy(struct ieee80211_key *key,
void ieee80211_key_free_unused(struct ieee80211_key *key) void ieee80211_key_free_unused(struct ieee80211_key *key)
{ {
if (!key)
return;
WARN_ON(key->sdata || key->local); WARN_ON(key->sdata || key->local);
ieee80211_key_free_common(key); ieee80211_key_free_common(key);
} }
...@@ -854,7 +857,7 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -854,7 +857,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
* can cause warnings to appear. * can cause warnings to appear.
*/ */
bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION;
int ret = -EOPNOTSUPP; int ret;
mutex_lock(&sdata->local->key_mtx); mutex_lock(&sdata->local->key_mtx);
...@@ -868,8 +871,10 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -868,8 +871,10 @@ int ieee80211_key_link(struct ieee80211_key *key,
* the same cipher. Enforce the assumption for pairwise keys. * the same cipher. Enforce the assumption for pairwise keys.
*/ */
if ((alt_key && alt_key->conf.cipher != key->conf.cipher) || 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; goto out;
}
} else if (sta) { } else if (sta) {
struct link_sta_info *link_sta = &sta->deflink; struct link_sta_info *link_sta = &sta->deflink;
int link_id = key->conf.link_id; int link_id = key->conf.link_id;
...@@ -895,18 +900,19 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -895,18 +900,19 @@ int ieee80211_key_link(struct ieee80211_key *key,
/* Non-pairwise keys must also not switch the cipher on rekey */ /* Non-pairwise keys must also not switch the cipher on rekey */
if (!pairwise) { 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; goto out;
} }
}
/* /*
* Silently accept key re-installation without really installing the * Silently accept key re-installation without really installing the
* new version of the key to avoid nonce reuse or replay issues. * new version of the key to avoid nonce reuse or replay issues.
*/ */
if (ieee80211_key_identical(sdata, old_key, key)) { if (ieee80211_key_identical(sdata, old_key, key)) {
ieee80211_key_free_unused(key);
ret = -EALREADY; ret = -EALREADY;
goto out; goto unlock;
} }
key->local = sdata->local; key->local = sdata->local;
...@@ -930,7 +936,11 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -930,7 +936,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
ieee80211_key_free(key, delay_tailroom); ieee80211_key_free(key, delay_tailroom);
} }
key = NULL;
out: out:
ieee80211_key_free_unused(key);
unlock:
mutex_unlock(&sdata->local->key_mtx); mutex_unlock(&sdata->local->key_mtx);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment