Skip to content

Commit d097ae0

Browse files
committed
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 <[email protected]>
1 parent 31db78a commit d097ae0

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

net/mac80211/key.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,9 @@ static void ieee80211_key_destroy(struct ieee80211_key *key,
802802

803803
void ieee80211_key_free_unused(struct ieee80211_key *key)
804804
{
805+
if (!key)
806+
return;
807+
805808
WARN_ON(key->sdata || key->local);
806809
ieee80211_key_free_common(key);
807810
}
@@ -854,7 +857,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
854857
* can cause warnings to appear.
855858
*/
856859
bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION;
857-
int ret = -EOPNOTSUPP;
860+
int ret;
858861

859862
mutex_lock(&sdata->local->key_mtx);
860863

@@ -868,8 +871,10 @@ int ieee80211_key_link(struct ieee80211_key *key,
868871
* the same cipher. Enforce the assumption for pairwise keys.
869872
*/
870873
if ((alt_key && alt_key->conf.cipher != key->conf.cipher) ||
871-
(old_key && old_key->conf.cipher != key->conf.cipher))
874+
(old_key && old_key->conf.cipher != key->conf.cipher)) {
875+
ret = -EOPNOTSUPP;
872876
goto out;
877+
}
873878
} else if (sta) {
874879
struct link_sta_info *link_sta = &sta->deflink;
875880
int link_id = key->conf.link_id;
@@ -895,18 +900,19 @@ int ieee80211_key_link(struct ieee80211_key *key,
895900

896901
/* Non-pairwise keys must also not switch the cipher on rekey */
897902
if (!pairwise) {
898-
if (old_key && old_key->conf.cipher != key->conf.cipher)
903+
if (old_key && old_key->conf.cipher != key->conf.cipher) {
904+
ret = -EOPNOTSUPP;
899905
goto out;
906+
}
900907
}
901908

902909
/*
903910
* Silently accept key re-installation without really installing the
904911
* new version of the key to avoid nonce reuse or replay issues.
905912
*/
906913
if (ieee80211_key_identical(sdata, old_key, key)) {
907-
ieee80211_key_free_unused(key);
908914
ret = -EALREADY;
909-
goto out;
915+
goto unlock;
910916
}
911917

912918
key->local = sdata->local;
@@ -930,7 +936,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
930936
ieee80211_key_free(key, delay_tailroom);
931937
}
932938

939+
key = NULL;
940+
933941
out:
942+
ieee80211_key_free_unused(key);
943+
unlock:
934944
mutex_unlock(&sdata->local->key_mtx);
935945

936946
return ret;

0 commit comments

Comments
 (0)