From: Benjamin Berg <benjamin.berg@xxxxxxxxx> This adds a test that tries to start an MLD AP multiple times, failing it either in different locations or not at all. --- Hi, This test seems triggers various existing problems in hostapd. The failures I see are: 1. With the current fail order, hostapd crashes on the second try 2. If fail_pos=2 is run, then hostapd leaks memory 3. When just running fail_pos=0 twice, the second startup fails Note that I am not sure about #3, because I am not certain that the link_remove() calls are actually correct. Either way, it seems obvious that there are some problems in hostapd currently. It would be nice if someone could look into these. Thanks, Benjamin Signed-off-by: Benjamin Berg <benjamin.berg@xxxxxxxxx> --- hostapd/ctrl_iface.c | 12 +++++++++++ src/ap/hostapd.c | 4 ++++ tests/hwsim/test_ap_eht.py | 42 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/hwsim/test_ap_eht.py diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 3b410ac77a..816e871e14 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -5914,6 +5914,18 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx, interfaces, buf + 10, reply, reply_size); } else if (os_strcmp(buf, "TERMINATE") == 0) { eloop_terminate(); +#ifdef CONFIG_TESTING_OPTIONS + } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) { + if (testing_set_fail_pattern(true, buf + 16) < 0) + reply_len = -1; + } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) { + reply_len = testing_get_fail_pattern(true, reply, reply_size); + } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) { + if (testing_set_fail_pattern(false, buf + 10) < 0) + reply_len = -1; + } else if (os_strcmp(buf, "GET_FAIL") == 0) { + reply_len = testing_get_fail_pattern(false, reply, reply_size); +#endif /* CONFIG_TESTING_OPTIONS */ } else { wpa_printf(MSG_DEBUG, "Unrecognized global ctrl_iface command " "ignored"); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index f2f0c29493..ad101b9187 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -2828,6 +2828,10 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err) unsigned int i; int not_ready_in_sync_ifaces = 0; + if (TEST_FAIL_TAG(hapd->conf->iface)) { + err = -1; + } + if (!iface->need_to_start_in_sync) return hostapd_setup_interface_complete_sync(iface, err); diff --git a/tests/hwsim/test_ap_eht.py b/tests/hwsim/test_ap_eht.py new file mode 100644 index 0000000000..543e9c1d2c --- /dev/null +++ b/tests/hwsim/test_ap_eht.py @@ -0,0 +1,42 @@ +# EHT AP tests +# Copyright (c) 2025, Intel Corporation +# +# This software may be distributed under the terms of the BSD license. +# See README for more details. + +from utils import * +from hwsim import HWSimRadio +from hostapd import HostapdGlobal +from test_eht import eht_mld_enable_ap, eht_mld_ap_wpa2_params + +def test_mld_ap_start_fail(dev, apdev): + """Check various MLD AP startup combinations and failures""" + + hapd_global = HostapdGlobal(apdev) + + with HWSimRadio(use_mlo=True) as (hapd0_radio, hapd0_iface): + + # Try two clean runs last + for fail_pos in (1, 2, 0, 0): + logger.info("Failing pos: %d", fail_pos) + with fail_test(hapd_global, fail_pos, + f"{hapd0_iface};hostapd_setup_interface_complete"): + ssid = "mld_ap_owe" + params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2") + + hapd0_0 = None + hapd0_1 = None + + try: + hapd0_0 = eht_mld_enable_ap(hapd0_iface, 0, params) + params['channel'] = '6' + hapd0_1 = eht_mld_enable_ap(hapd0_iface, 1, params) + except: + # We expect a failure (but not on the last run) + assert fail_pos != 0, "Expected success without injected failure" + finally: + if hapd0_0 is not None: + hapd0_0.link_remove() + if hapd0_1 is not None: + hapd0_1.link_remove() + -- 2.50.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap