Hi, Last week I posted an email discussing a regression from 2.9 a FreeBSD user discovered. I was able to reproduce the problem locally using a Netgear WNDR3700v3 (I have two of these, results the same on both). The problem occurs when the primary VAP is configured with WPA and the secondary VAP (guest network on Netgear) is open and unprotected. What I'm seeing is an IE that causes wpa_supplicant to assume WPA even though key_mgmt=NONE. The hackish patch below works around the problem: diff --git a/contrib/wpa/src/drivers/driver_bsd.c b/contrib/wpa/src/drivers/ driver_bsd.c index c455bc931036..b39198b7249b 100644 --- a/contrib/wpa/src/drivers/driver_bsd.c +++ b/contrib/wpa/src/drivers/driver_bsd.c @@ -1209,6 +1209,10 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) int privacy; int ret = 0; + /* XXX woraround for PR/264238 until a better solution can be found */ + const u8 *wpa_ie_save; + size_t wpa_ie_len_save; + wpa_printf(MSG_DEBUG, "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" , __func__ @@ -1256,9 +1260,26 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) ret = -1; if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0) ret = -1; + + /* XXX woraround for PR/264238 until a better solution can be found */ + if (params->pairwise_suite == WPA_CIPHER_NONE && + params->group_suite == WPA_CIPHER_NONE && + params->key_mgmt_suite == WPA_KEY_MGMT_NONE && + params->wpa_ie_len != 0) { + wpa_ie_save = params->wpa_ie; + wpa_ie_len_save = params->wpa_ie_len; + params->wpa_ie = NULL; + params->wpa_ie_len = 0; + } else { + wpa_ie_save = NULL; + wpa_ie_len_save = 0; + } + /* XXX error handling is wrong but unclear what to do... */ - if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) - return -1; + if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) { + ret = -1; + goto bsd_assoc_exit; + } privacy = !(params->pairwise_suite == WPA_CIPHER_NONE && params->group_suite == WPA_CIPHER_NONE && @@ -1266,20 +1287,26 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) params->wpa_ie_len == 0); wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy); - if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) - return -1; + if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) { + ret = -1; + goto bsd_assoc_exit; + } if (params->wpa_ie_len && set80211param(drv, IEEE80211_IOC_WPA, - params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0) - return -1; + params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0) { + ret = -1; + goto bsd_assoc_exit; + } /* * NB: interface must be marked UP for association * or scanning (ap_scan=2) */ - if (bsd_get_iface_flags(drv) < 0) - return -1; + if (bsd_get_iface_flags(drv) < 0) { + ret = -1; + goto bsd_assoc_exit; + } os_memset(&mlme, 0, sizeof(mlme)); mlme.im_op = IEEE80211_MLME_ASSOC; @@ -1289,7 +1316,10 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) if (params->bssid != NULL) os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) - return -1; + ret = -1; +bsd_assoc_exit: + params->wpa_ie = wpa_ie_save; + params->wpa_ie_len = wpa_ie_len_save; return ret; } However, the code this patch touches has been in driver_bsd.c since 2008 so, obviously the code this patch addresses is not the cause of the regression from 2.9 to 2.10. The problem lies elsewhere and the above patch treats the symptom and not the cause. The problem is I don't have nearly enough experience with hostap internals to identify the hostap commit that likely caused the regression. Where might I look to discover in hostap where the IE is received from the AP, and if this jogs someone's recollection of the patch I'd be grateful. In summary, based on my testing this only occurs on a secondary open unencrypted VAP when the primary VAP is configured for WPA. P.S. The setting of params->wpa_ie back to its original value at the end of the patch is in the one case I can find where this memory is obtained through os_malloc(), avoiding a memory leak. This is a hackish workaround but I'd prefer finding a better solution. Any help would be muchly appreciated. -- Cheers, Cy Schubert <Cy.Schubert@xxxxxxxxxxxxx> FreeBSD UNIX: <cy@xxxxxxxxxxx> Web: http://www.FreeBSD.org NTP: <cy@xxxxxxxxxx> Web: https://nwtime.org e**(i*pi)+1=0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap