[wpa_supplicant/f20] Don't disconnect when PMKSA cache gets too large (rh #1016707)

Daniel Williams dcbw at fedoraproject.org
Mon Nov 18 22:02:13 UTC 2013


commit ec309e6b4baad15b326f0fbcb73c01637dd1564a
Author: Dan Williams <dcbw at redhat.com>
Date:   Mon Nov 18 16:02:55 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                                |    9 +-
 2 files changed, 158 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 9d3b81a..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: 7%{?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,9 @@ 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
 


More information about the scm-commits mailing list