diff mbox series

[1/4] AP MLD: fix deferred first link BSS's radius, auth server and 802.1X initialization

Message ID 20240422111906.2928263-2-quic_adisi@quicinc.com
State Accepted
Headers show
Series MLO related fixes for scan/ACS | expand

Commit Message

Aditya Kumar Singh April 22, 2024, 11:19 a.m. UTC
Currently, radius client, auth server and 802.1X are copied from first
link's BSS into the non-first link during its setup. However, there could
be a case where the first link is not initialized fully because of
ACS/HT40 SCAN/DFS. Hence, in such cases, NULL is getting copied and later
it leads to segmentation fault.

Add changes to initialize those on behalf of the first link if such be the
case and update it so that next time other non-first link can use it.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 src/ap/authsrv.c    | 16 ++++++--
 src/ap/hostapd.c    | 96 +++++++++++++++++++++++++++++----------------
 src/ap/ieee802_1x.c | 15 +++++--
 3 files changed, 86 insertions(+), 41 deletions(-)
diff mbox series

Patch

diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c
index 6ed4d063349b..bfb89cc9b6a1 100644
--- a/src/ap/authsrv.c
+++ b/src/ap/authsrv.c
@@ -258,13 +258,21 @@  int authsrv_init(struct hostapd_data *hapd)
 {
 #ifdef CONFIG_IEEE80211BE
 	if (!hostapd_mld_is_first_bss(hapd)) {
-		struct hostapd_data *first;
-
-		wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
+		struct hostapd_data *first = hostapd_mld_get_first_bss(hapd);
 
-		first = hostapd_mld_get_first_bss(hapd);
 		if (!first)
 			return -1;
+
+		if (!first->eap_cfg) {
+			wpa_printf(MSG_DEBUG,
+				   "MLD: First BSS auth_serv does not exist. Init on its behalf");
+
+			if (authsrv_init(first))
+				return -1;
+		}
+
+		wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
+
 #ifdef EAP_TLS_FUNCS
 		hapd->ssl_ctx = first->ssl_ctx;
 #endif /* EAP_TLS_FUNCS */
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 130b6ebc6b21..eb5bf3371456 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1307,6 +1307,58 @@  static int hostapd_start_beacon(struct hostapd_data *hapd,
 }
 
 
+#ifndef CONFIG_NO_RADIUS
+static int hostapd_bss_radius_init(struct hostapd_data *hapd)
+{
+	struct hostapd_bss_config *conf;
+
+	if (!hapd)
+		return -1;
+
+	conf = hapd->conf;
+
+	if (hapd->radius) {
+		wpa_printf(MSG_DEBUG, "Skipping RADIUS client init (already done)");
+		return 0;
+	}
+
+	hapd->radius = radius_client_init(hapd, conf->radius);
+	if (!hapd->radius) {
+		wpa_printf(MSG_ERROR,
+			   "RADIUS client initialization failed.");
+		return -1;
+	}
+
+	if (conf->radius_das_port) {
+		struct radius_das_conf das_conf;
+
+		os_memset(&das_conf, 0, sizeof(das_conf));
+		das_conf.port = conf->radius_das_port;
+		das_conf.shared_secret = conf->radius_das_shared_secret;
+		das_conf.shared_secret_len =
+			conf->radius_das_shared_secret_len;
+		das_conf.client_addr = &conf->radius_das_client_addr;
+		das_conf.time_window = conf->radius_das_time_window;
+		das_conf.require_event_timestamp =
+			conf->radius_das_require_event_timestamp;
+		das_conf.require_message_authenticator =
+			conf->radius_das_require_message_authenticator;
+		das_conf.ctx = hapd;
+		das_conf.disconnect = hostapd_das_disconnect;
+		das_conf.coa = hostapd_das_coa;
+		hapd->radius_das = radius_das_init(&das_conf);
+		if (!hapd->radius_das) {
+			wpa_printf(MSG_ERROR,
+				   "RADIUS DAS initialization failed.");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+#endif /* CONFIG_NO_RADIUS */
+
+
 /**
  * hostapd_setup_bss - Per-BSS setup (initialization)
  * @hapd: Pointer to BSS data
@@ -1540,46 +1592,24 @@  setup_mld:
 #endif /* CONFIG_SQLITE */
 
 	if (hostapd_mld_is_first_bss(hapd)) {
-		hapd->radius = radius_client_init(hapd, conf->radius);
-		if (!hapd->radius) {
-			wpa_printf(MSG_ERROR,
-				   "RADIUS client initialization failed.");
+		if (hostapd_bss_radius_init(hapd))
+			return -1;
+	} else {
+#ifdef CONFIG_IEEE80211BE
+		struct hostapd_data *f_bss = hostapd_mld_get_first_bss(hapd);
+		if (!f_bss)
 			return -1;
-		}
 
-		if (conf->radius_das_port) {
-			struct radius_das_conf das_conf;
-
-			os_memset(&das_conf, 0, sizeof(das_conf));
-			das_conf.port = conf->radius_das_port;
-			das_conf.shared_secret = conf->radius_das_shared_secret;
-			das_conf.shared_secret_len =
-				conf->radius_das_shared_secret_len;
-			das_conf.client_addr = &conf->radius_das_client_addr;
-			das_conf.time_window = conf->radius_das_time_window;
-			das_conf.require_event_timestamp =
-				conf->radius_das_require_event_timestamp;
-			das_conf.require_message_authenticator =
-				conf->radius_das_require_message_authenticator;
-			das_conf.ctx = hapd;
-			das_conf.disconnect = hostapd_das_disconnect;
-			das_conf.coa = hostapd_das_coa;
-			hapd->radius_das = radius_das_init(&das_conf);
-			if (!hapd->radius_das) {
-				wpa_printf(MSG_ERROR,
-					   "RADIUS DAS initialization failed.");
+		if (!f_bss->radius) {
+			wpa_printf(MSG_DEBUG,
+				   "MLD: First BSS RADIUS client does not exist. Init on its behalf");
+
+			if (hostapd_bss_radius_init(f_bss))
 				return -1;
-			}
 		}
-	} else {
-#ifdef CONFIG_IEEE80211BE
-		struct hostapd_data *f_bss;
 
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using RADIUS client of the first BSS");
-		f_bss = hostapd_mld_get_first_bss(hapd);
-		if (!f_bss)
-			return -1;
 		hapd->radius = f_bss->radius;
 		hapd->radius_das = f_bss->radius_das;
 #endif /* CONFIG_IEEE80211BE */
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 8e98b6521695..857f0d184774 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -2541,14 +2541,21 @@  int ieee802_1x_init(struct hostapd_data *hapd)
 
 #ifdef CONFIG_IEEE80211BE
 	if (!hostapd_mld_is_first_bss(hapd)) {
-		struct hostapd_data *first;
+		struct hostapd_data *first = hostapd_mld_get_first_bss(hapd);
+		if (!first)
+			return -1;
+
+		if (!first->eapol_auth) {
+			wpa_printf(MSG_DEBUG,
+				  "MLD: First BSS IEEE 802.1X state machine does not exist. Init on its behalf");
+
+			if (ieee802_1x_init(first))
+				return -1;
+		}
 
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using IEEE 802.1X state machine of the first BSS");
 
-		first = hostapd_mld_get_first_bss(hapd);
-		if (!first)
-			return -1;
 		hapd->eapol_auth = first->eapol_auth;
 		return 0;
 	}