Cherry pick the patches recommended in the hostapd security advisory 2026-1: https://w1.fi/security/2026-1/missing-ml-parsing-validation.txt Vulnerability Vulnerabilities in parsing and use of received multi-link (MLO/EHT/IEEE 802.11be/Wi-Fi 7) information has been identified in hostapd and wpa_supplicant. These issues show up in various cases where frames including information on affiliated links are parsed and processed in both AP and STA modes. The issues can result in process termination due to buffer read overflow checks and memory corruption. The issues for AP mode (hostapd or wpa_supplicant) can result in denial-of-service attacks due to process termination and small memory corruption that could theoretically cause other issues, but it does not seem likely that those could be exploiting in practice. Affected areas can be reached by sending invalid Management frames without needing authentication or user action on the target device. CVE-2026-58374 Link: https://github.com/openwrt/openwrt/pull/24043 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
363 lines
10 KiB
Diff
363 lines
10 KiB
Diff
From: Felix Fietkau <nbd@openwrt.org>
|
|
Date: Sat, 23 Jan 2010 08:28:26 +0000
|
|
Subject: [PATCH] Add option to build a multicall binary
|
|
|
|
This allows building both hostapd and wpa_supplicant as a single binary
|
|
(wpad).
|
|
|
|
--- a/hostapd/Makefile
|
|
+++ b/hostapd/Makefile
|
|
@@ -1,6 +1,7 @@
|
|
ALL=hostapd hostapd_cli
|
|
CONFIG_FILE = .config
|
|
|
|
+-include $(if $(MULTICALL), ../wpa_supplicant/.config)
|
|
include ../src/build.rules
|
|
|
|
ifdef LIBS
|
|
@@ -200,7 +201,8 @@ endif
|
|
|
|
ifdef CONFIG_NO_VLAN
|
|
CFLAGS += -DCONFIG_NO_VLAN
|
|
-else
|
|
+endif
|
|
+ifneq ($(findstring CONFIG_NO_VLAN,$(CFLAGS)), CONFIG_NO_VLAN)
|
|
OBJS += ../src/ap/vlan_init.o
|
|
OBJS += ../src/ap/vlan_ifconfig.o
|
|
OBJS += ../src/ap/vlan.o
|
|
@@ -360,10 +362,14 @@ CFLAGS += -DCONFIG_MBO
|
|
OBJS += ../src/ap/mbo_ap.o
|
|
endif
|
|
|
|
+ifndef MULTICALL
|
|
+CFLAGS += -DNO_SUPPLICANT
|
|
+endif
|
|
+
|
|
include ../src/drivers/drivers.mak
|
|
-OBJS += $(DRV_AP_OBJS)
|
|
-CFLAGS += $(DRV_AP_CFLAGS)
|
|
-LDFLAGS += $(DRV_AP_LDFLAGS)
|
|
+OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS)))
|
|
+CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS))
|
|
+LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS))
|
|
LIBS += $(DRV_AP_LIBS)
|
|
|
|
ifdef CONFIG_L2_PACKET
|
|
@@ -1430,6 +1436,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
|
|
_OBJS_VAR := OBJS
|
|
include ../src/objs.mk
|
|
|
|
+hostapd_multi.a: $(BCHECK) $(OBJS)
|
|
+ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c
|
|
+ @$(E) " CC " $<
|
|
+ @rm -f $@
|
|
+ @$(AR) cr $@ hostapd_multi.o $(OBJS)
|
|
+
|
|
hostapd: $(OBJS)
|
|
$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
|
@$(E) " LD " $@
|
|
@@ -1518,6 +1530,12 @@ include ../src/objs.mk
|
|
_OBJS_VAR := SOBJS
|
|
include ../src/objs.mk
|
|
|
|
+dump_cflags:
|
|
+ @printf "%s " "$(CFLAGS)"
|
|
+
|
|
+dump_ldflags:
|
|
+ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)"
|
|
+
|
|
nt_password_hash: $(NOBJS)
|
|
$(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n)
|
|
@$(E) " LD " $@
|
|
--- a/hostapd/main.c
|
|
+++ b/hostapd/main.c
|
|
@@ -744,6 +744,11 @@ fail:
|
|
return -1;
|
|
}
|
|
|
|
+void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
+
|
|
+void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
|
|
#ifdef CONFIG_WPS
|
|
static int gen_uuid(const char *txt_addr)
|
|
@@ -868,6 +873,8 @@ int main(int argc, char *argv[])
|
|
return -1;
|
|
#endif /* CONFIG_DPP */
|
|
|
|
+ wpa_supplicant_event = hostapd_wpa_event;
|
|
+ wpa_supplicant_event_global = hostapd_wpa_event_global;
|
|
for (;;) {
|
|
c = getopt(argc, argv, "b:Bde:f:hi:KP:sSTtu:vg:G:qz:");
|
|
if (c < 0)
|
|
--- a/src/ap/drv_callbacks.c
|
|
+++ b/src/ap/drv_callbacks.c
|
|
@@ -2596,8 +2596,8 @@ static void hostapd_mld_iface_disable(st
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
|
|
-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|
- union wpa_event_data *data)
|
|
+void hostapd_wpa_event(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data)
|
|
{
|
|
struct hostapd_data *hapd = ctx;
|
|
struct sta_info *sta;
|
|
@@ -2967,7 +2967,7 @@ void wpa_supplicant_event(void *ctx, enu
|
|
}
|
|
|
|
|
|
-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
+void hostapd_wpa_event_global(void *ctx, enum wpa_event_type event,
|
|
union wpa_event_data *data)
|
|
{
|
|
struct hapd_interfaces *interfaces = ctx;
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -7313,8 +7313,8 @@ union wpa_event_data {
|
|
* Driver wrapper code should call this function whenever an event is received
|
|
* from the driver.
|
|
*/
|
|
-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|
- union wpa_event_data *data);
|
|
+extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
|
|
/**
|
|
* wpa_supplicant_event_global - Report a driver event for wpa_supplicant
|
|
@@ -7326,7 +7326,7 @@ void wpa_supplicant_event(void *ctx, enu
|
|
* Same as wpa_supplicant_event(), but we search for the interface in
|
|
* wpa_global.
|
|
*/
|
|
-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
+extern void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event,
|
|
union wpa_event_data *data);
|
|
|
|
/*
|
|
--- a/src/drivers/drivers.c
|
|
+++ b/src/drivers/drivers.c
|
|
@@ -10,6 +10,10 @@
|
|
#include "utils/common.h"
|
|
#include "driver.h"
|
|
|
|
+void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
+void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
|
|
const struct wpa_driver_ops *const wpa_drivers[] =
|
|
{
|
|
--- a/wpa_supplicant/Makefile
|
|
+++ b/wpa_supplicant/Makefile
|
|
@@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.servic
|
|
EXTRA_TARGETS=dynamic_eap_methods
|
|
|
|
CONFIG_FILE=.config
|
|
+-include $(if $(MULTICALL),../hostapd/.config)
|
|
include ../src/build.rules
|
|
|
|
ifdef CONFIG_BUILD_PASN_SO
|
|
@@ -411,7 +412,9 @@ endif
|
|
ifdef CONFIG_IBSS_RSN
|
|
NEED_RSN_AUTHENTICATOR=y
|
|
CFLAGS += -DCONFIG_IBSS_RSN
|
|
+ifndef MULTICALL
|
|
CFLAGS += -DCONFIG_NO_VLAN
|
|
+endif
|
|
OBJS += ibss_rsn.o
|
|
endif
|
|
|
|
@@ -1020,6 +1023,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
|
|
CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
|
|
LIBS += -ldl -rdynamic
|
|
endif
|
|
+else
|
|
+ ifdef MULTICALL
|
|
+ OBJS += ../src/eap_common/eap_common.o
|
|
+ endif
|
|
endif
|
|
|
|
ifdef CONFIG_AP
|
|
@@ -1027,9 +1034,11 @@ NEED_EAP_COMMON=y
|
|
NEED_RSN_AUTHENTICATOR=y
|
|
CFLAGS += -DCONFIG_AP
|
|
OBJS += ap.o
|
|
+ifndef MULTICALL
|
|
CFLAGS += -DCONFIG_NO_RADIUS
|
|
CFLAGS += -DCONFIG_NO_ACCOUNTING
|
|
CFLAGS += -DCONFIG_NO_VLAN
|
|
+endif
|
|
OBJS += ../src/ap/hostapd.o
|
|
OBJS += ../src/ap/wpa_auth_glue.o
|
|
OBJS += ../src/ap/utils.o
|
|
@@ -1121,6 +1130,12 @@ endif
|
|
ifdef CONFIG_HS20
|
|
OBJS += ../src/ap/hs20.o
|
|
endif
|
|
+else
|
|
+ ifdef MULTICALL
|
|
+ OBJS += ../src/eap_server/eap_server.o
|
|
+ OBJS += ../src/eap_server/eap_server_identity.o
|
|
+ OBJS += ../src/eap_server/eap_server_methods.o
|
|
+ endif
|
|
endif
|
|
|
|
ifdef CONFIG_MBO
|
|
@@ -1130,7 +1145,9 @@ NEED_GAS=y
|
|
endif
|
|
|
|
ifdef NEED_RSN_AUTHENTICATOR
|
|
+ifndef MULTICALL
|
|
CFLAGS += -DCONFIG_NO_RADIUS
|
|
+endif
|
|
NEED_AES_WRAP=y
|
|
OBJS += ../src/ap/wpa_auth.o
|
|
OBJS += ../src/ap/wpa_auth_ie.o
|
|
@@ -2130,6 +2147,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
|
|
|
|
_OBJS_VAR := OBJS
|
|
include ../src/objs.mk
|
|
+wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs)
|
|
+ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c
|
|
+ @$(E) " CC " $<
|
|
+ @rm -f $@
|
|
+ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS)
|
|
+
|
|
wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
|
|
$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
|
|
@$(E) " LD " $@
|
|
@@ -2262,6 +2285,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK)
|
|
$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
|
|
@$(E) " sed" $<
|
|
|
|
+dump_cflags:
|
|
+ @printf "%s " "$(CFLAGS)"
|
|
+
|
|
+dump_ldflags:
|
|
+ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)"
|
|
+
|
|
wpa_supplicant.exe: wpa_supplicant
|
|
mv -f $< $@
|
|
wpa_cli.exe: wpa_cli
|
|
--- a/wpa_supplicant/eapol_test.c
|
|
+++ b/wpa_supplicant/eapol_test.c
|
|
@@ -31,7 +31,12 @@
|
|
#include "ctrl_iface.h"
|
|
#include "pcsc_funcs.h"
|
|
#include "wpas_glue.h"
|
|
+#include "drivers/driver.h"
|
|
|
|
+void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
+void (*wpa_supplicant_event_global)(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
|
|
const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
|
|
|
|
@@ -1328,6 +1333,10 @@ static void usage(void)
|
|
"option several times.\n");
|
|
}
|
|
|
|
+extern void supplicant_event(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
+extern void supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
@@ -1351,6 +1360,8 @@ int main(int argc, char *argv[])
|
|
if (os_program_init())
|
|
return -1;
|
|
|
|
+ wpa_supplicant_event = supplicant_event;
|
|
+ wpa_supplicant_event_global = supplicant_event_global;
|
|
hostapd_logger_register_cb(hostapd_logger_cb);
|
|
|
|
os_memset(&eapol_test, 0, sizeof(eapol_test));
|
|
--- a/wpa_supplicant/events.c
|
|
+++ b/wpa_supplicant/events.c
|
|
@@ -6643,8 +6643,8 @@ static int wpas_pasn_auth(struct wpa_sup
|
|
#endif /* CONFIG_PASN */
|
|
|
|
|
|
-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|
- union wpa_event_data *data)
|
|
+void supplicant_event(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data)
|
|
{
|
|
struct wpa_supplicant *wpa_s = ctx;
|
|
int resched;
|
|
@@ -7638,7 +7638,7 @@ void wpa_supplicant_event(void *ctx, enu
|
|
}
|
|
|
|
|
|
-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
+void supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
union wpa_event_data *data)
|
|
{
|
|
struct wpa_supplicant *wpa_s;
|
|
--- a/wpa_supplicant/wpa_priv.c
|
|
+++ b/wpa_supplicant/wpa_priv.c
|
|
@@ -1042,8 +1042,8 @@ static void wpa_priv_send_ft_response(st
|
|
}
|
|
|
|
|
|
-void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|
- union wpa_event_data *data)
|
|
+static void supplicant_event(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data)
|
|
{
|
|
struct wpa_priv_interface *iface = ctx;
|
|
|
|
@@ -1106,7 +1106,7 @@ void wpa_supplicant_event(void *ctx, enu
|
|
}
|
|
|
|
|
|
-void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
+void supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
union wpa_event_data *data)
|
|
{
|
|
struct wpa_priv_global *global = ctx;
|
|
@@ -1220,6 +1220,8 @@ int main(int argc, char *argv[])
|
|
if (os_program_init())
|
|
return -1;
|
|
|
|
+ wpa_supplicant_event = supplicant_event;
|
|
+ wpa_supplicant_event_global = supplicant_event_global;
|
|
wpa_priv_fd_workaround();
|
|
|
|
os_memset(&global, 0, sizeof(global));
|
|
--- a/wpa_supplicant/wpa_supplicant.c
|
|
+++ b/wpa_supplicant/wpa_supplicant.c
|
|
@@ -8259,7 +8259,6 @@ struct wpa_interface * wpa_supplicant_ma
|
|
return NULL;
|
|
}
|
|
|
|
-
|
|
/**
|
|
* wpa_supplicant_match_existing - Match existing interfaces
|
|
* @global: Pointer to global data from wpa_supplicant_init()
|
|
@@ -8294,6 +8293,11 @@ static int wpa_supplicant_match_existing
|
|
|
|
#endif /* CONFIG_MATCH_IFACE */
|
|
|
|
+extern void supplicant_event(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
+
|
|
+extern void supplicant_event_global(void *ctx, enum wpa_event_type event,
|
|
+ union wpa_event_data *data);
|
|
|
|
/**
|
|
* wpa_supplicant_add_iface - Add a new network interface
|
|
@@ -8550,6 +8554,8 @@ struct wpa_global * wpa_supplicant_init(
|
|
#ifndef CONFIG_NO_WPA_MSG
|
|
wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
|
|
#endif /* CONFIG_NO_WPA_MSG */
|
|
+ wpa_supplicant_event = supplicant_event;
|
|
+ wpa_supplicant_event_global = supplicant_event_global;
|
|
|
|
if (params->wpa_debug_file_path)
|
|
wpa_debug_open_file(params->wpa_debug_file_path);
|