[wpa_supplicant/f19] Don't disconnect when PMKSA cache gets too large (rh #1016707)
Daniel Williams
dcbw at fedoraproject.org
Mon Nov 18 22:04:56 UTC 2013
commit 78f572133522f0bb4c64ed4e150e0d0d3d90d213
Author: Dan Williams <dcbw at redhat.com>
Date: Mon Nov 18 16:05:18 2013 -0600
Don't disconnect when PMKSA cache gets too large (rh #1016707)
...-Fix-OKC-based-PMKSA-cache-entry-clearing.patch | 150 ++++++++++++++++++++
wpa_supplicant.spec | 12 ++-
2 files changed, 161 insertions(+), 1 deletions(-)
---
diff --git a/0001-Fix-OKC-based-PMKSA-cache-entry-clearing.patch b/0001-Fix-OKC-based-PMKSA-cache-entry-clearing.patch
new file mode 100644
index 0000000..91fdc12
--- /dev/null
+++ b/0001-Fix-OKC-based-PMKSA-cache-entry-clearing.patch
@@ -0,0 +1,150 @@
+From 4033935dd9098938838d6d7934ceb65f92a1fa3c Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni at qca.qualcomm.com>
+Date: Wed, 22 May 2013 13:24:30 +0300
+Subject: [PATCH] Fix OKC-based PMKSA cache entry clearing
+
+Commit c3fea272747f738f5723fc577371fe03711d988f added a call to clear
+all other PMKSA cache entries for the same network if the PMKSA cache
+entry of the current AP changed. This was needed to fix OKC cases since
+the other APs would likely use the new PMK in the future. However, this
+ended up clearing entries in cases where that is not desired and this
+resulted in needing additional full EAP authentication with networks
+that did not support OKC if wpa_supplicant was configured to try to use
+it.
+
+Make PMKSA cache entry flushing more limited so that the other entries
+are removed only if they used the old PMK that was replaced for the
+current AP and only if that PMK had previously been used successfully
+(i.e., opportunistic flag was already cleared back to 0 in
+wpa_supplicant_key_neg_complete()). This is still enough to fix the
+issue described in that older commit while not causing problems for
+standard PMKSA caching operations even if OKC is enabled in
+wpa_supplicant configuration.
+
+Signed-hostap: Jouni Malinen <jouni at qca.qualcomm.com>
+---
+ src/rsn_supp/pmksa_cache.c | 27 ++++++++++++++++++++-------
+ src/rsn_supp/pmksa_cache.h | 3 ++-
+ src/rsn_supp/wpa.c | 2 +-
+ 3 files changed, 23 insertions(+), 9 deletions(-)
+
+diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
+index df67583..93056ea 100644
+--- a/src/rsn_supp/pmksa_cache.c
++++ b/src/rsn_supp/pmksa_cache.c
+@@ -160,25 +160,31 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
+ os_free(entry);
+ return pos;
+ }
+ if (prev == NULL)
+ pmksa->pmksa = pos->next;
+ else
+ prev->next = pos->next;
+- wpa_printf(MSG_DEBUG, "RSN: Replace PMKSA entry for "
+- "the current AP");
+- pmksa_cache_free_entry(pmksa, pos, PMKSA_REPLACE);
+
+ /*
+ * If OKC is used, there may be other PMKSA cache
+ * entries based on the same PMK. These needs to be
+ * flushed so that a new entry can be created based on
+- * the new PMK.
++ * the new PMK. Only clear other entries if they have a
++ * matching PMK and this PMK has been used successfully
++ * with the current AP, i.e., if opportunistic flag has
++ * been cleared in wpa_supplicant_key_neg_complete().
+ */
+- pmksa_cache_flush(pmksa, network_ctx);
++ wpa_printf(MSG_DEBUG, "RSN: Replace PMKSA entry for "
++ "the current AP and any PMKSA cache entry "
++ "that was based on the old PMK");
++ if (!pos->opportunistic)
++ pmksa_cache_flush(pmksa, network_ctx, pos->pmk,
++ pos->pmk_len);
++ pmksa_cache_free_entry(pmksa, pos, PMKSA_REPLACE);
+ break;
+ }
+ prev = pos;
+ pos = pos->next;
+ }
+
+ if (pmksa->pmksa_count >= pmksa_cache_max_entries && pmksa->pmksa) {
+@@ -231,23 +237,30 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
+ }
+
+
+ /**
+ * pmksa_cache_flush - Flush PMKSA cache entries for a specific network
+ * @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
+ * @network_ctx: Network configuration context or %NULL to flush all entries
++ * @pmk: PMK to match for or %NYLL to match all PMKs
++ * @pmk_len: PMK length
+ */
+-void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx)
++void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
++ const u8 *pmk, size_t pmk_len)
+ {
+ struct rsn_pmksa_cache_entry *entry, *prev = NULL, *tmp;
+ int removed = 0;
+
+ entry = pmksa->pmksa;
+ while (entry) {
+- if (entry->network_ctx == network_ctx || network_ctx == NULL) {
++ if ((entry->network_ctx == network_ctx ||
++ network_ctx == NULL) &&
++ (pmk == NULL ||
++ (pmk_len == entry->pmk_len &&
++ os_memcmp(pmk, entry->pmk, pmk_len) == 0))) {
+ wpa_printf(MSG_DEBUG, "RSN: Flush PMKSA cache entry "
+ "for " MACSTR, MAC2STR(entry->aa));
+ if (prev)
+ prev->next = entry->next;
+ else
+ pmksa->pmksa = entry->next;
+ tmp = entry;
+diff --git a/src/rsn_supp/pmksa_cache.h b/src/rsn_supp/pmksa_cache.h
+index 6f3dfb3..d5aa229 100644
+--- a/src/rsn_supp/pmksa_cache.h
++++ b/src/rsn_supp/pmksa_cache.h
+@@ -62,15 +62,16 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm);
+ void pmksa_cache_clear_current(struct wpa_sm *sm);
+ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
+ const u8 *bssid, void *network_ctx,
+ int try_opportunistic);
+ struct rsn_pmksa_cache_entry *
+ pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
+ void *network_ctx, const u8 *aa);
+-void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx);
++void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
++ const u8 *pmk, size_t pmk_len);
+
+ #else /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */
+
+ static inline struct rsn_pmksa_cache *
+ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
+ void *ctx, int reason),
+ void *ctx, struct wpa_sm *sm)
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index e50404c..365a710 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -2618,15 +2618,15 @@ void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
+ os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
+ }
+
+
+ void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
+ {
+ #ifndef CONFIG_NO_WPA2
+- pmksa_cache_flush(sm->pmksa, network_ctx);
++ pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
+ #endif /* CONFIG_NO_WPA2 */
+ }
+
+
+ #ifdef CONFIG_WNM
+ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
+ {
+--
+1.8.3.1
+
diff --git a/wpa_supplicant.spec b/wpa_supplicant.spec
index ce4b24c..1df49c8 100644
--- a/wpa_supplicant.spec
+++ b/wpa_supplicant.spec
@@ -7,7 +7,7 @@ Summary: WPA/WPA2/IEEE 802.1X Supplicant
Name: wpa_supplicant
Epoch: 1
Version: 2.0
-Release: 6%{?dist}
+Release: 8%{?dist}
License: BSD
Group: System Environment/Base
Source0: http://w1.fi/releases/%{name}-%{version}%{rcver}%{snapshot}.tar.gz
@@ -42,6 +42,9 @@ Patch6: wpa_supplicant-gui-qt4.patch
Patch7: libnl3-includes.patch
# Less aggressive roaming; signal strength is wildly variable
Patch8: rh837402-less-aggressive-roaming.patch
+# Don't evict current AP from PMKSA cache when it's large
+Patch9: 0001-Fix-OKC-based-PMKSA-cache-entry-clearing.patch
+
%if %{build_libeap}
# Dirty hack for WiMAX
# http://linuxwimax.org/Download?action=AttachFile&do=get&target=wpa-1.5-README.txt
@@ -110,6 +113,7 @@ Don't use this unless you know what you're doing.
%patch6 -p1 -b .qt4
%patch7 -p1 -b .libnl3
%patch8 -p1 -b .rh837402-less-aggressive-roaming
+%patch9 -p1 -b .okc-current-fix
%build
pushd wpa_supplicant
@@ -253,6 +257,12 @@ fi
%endif
%changelog
+* Mon Nov 18 2013 Dan Williams <dcbw at redhat.com> - 1:2.0-8
+- Don't disconnect when PMKSA cache gets too large (rh #1016707)
+
+* Sun Aug 04 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1:2.0-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
* Wed Jul 10 2013 Dan Williams <dcbw at redhat.com> - 1:2.0-6
- Enable full RELRO/PIE/PIC for wpa_supplicant and libeap
- Fix changelog dates
More information about the scm-commits
mailing list