]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Ensure hostapd_deinit_driver() is called when driver_init() fails
authorRichard Yu <richard.yu@mitrastar.com.tw>
Tue, 15 Apr 2025 11:29:06 +0000 (19:29 +0800)
committerJouni Malinen <j@w1.fi>
Thu, 19 Jun 2025 09:23:58 +0000 (12:23 +0300)
Ensure hostapd_deinit_driver() is called when driver_init() fails in
both hostapd_enable_iface() and hostapd_add_iface().

When initializing an AP MLD interface, driver_init() first assigns a
valid private driver interface data pointer (drv_priv) to the
hostapd_iface structure. It then attempts to add a link by calling
hostapd_drv_link_add(). This call may fail under certain conditions,
such as ENETDOWN, EALREADY, or other transient errors.

In such failure cases, the hostapd interface retains a valid drv_priv
pointer, but no cleanup is performed. This results in an untracked
reference to the private driver interface data. While the memory backing
drv_priv will eventually be freed when the last interface sharing it is
deinitialized, the lack of cleanup in early failure paths can lead to
invalid memory access, potentially resulting in a segmentation fault.

Ensure that hostapd_deinit_driver() is invoked in both failure paths to
properly release driver resources and maintain consistency across
interface initialization routines.

Signed-off-by: Richard Yu <richard.yu@mitrastar.com.tw>
src/ap/hostapd.c

index 0dd2b89bb88bb3d9d26eaae0e3364ab77ceda05f..6c4513615e6036c5b18df2f02c64e4c5847037e4 100644 (file)
@@ -3604,8 +3604,12 @@ int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
 
        if (hapd_iface->interfaces == NULL ||
            hapd_iface->interfaces->driver_init == NULL ||
-           hapd_iface->interfaces->driver_init(hapd_iface))
+           hapd_iface->interfaces->driver_init(hapd_iface)) {
+               hostapd_deinit_driver(hapd_iface->bss[0]->driver,
+                                     hapd_iface->bss[0]->drv_priv,
+                                     hapd_iface);
                return -1;
+       }
 
        if (hostapd_setup_interface(hapd_iface)) {
                hostapd_deinit_driver(hapd_iface->bss[0]->driver,
@@ -3863,8 +3867,13 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
                }
 
                if (new_iface) {
-                       if (interfaces->driver_init(hapd_iface))
+                       if (interfaces->driver_init(hapd_iface)) {
+                               hostapd_deinit_driver(
+                                       hapd_iface->bss[0]->driver,
+                                       hapd_iface->bss[0]->drv_priv,
+                                       hapd_iface);
                                goto fail;
+                       }
 
                        if (hostapd_setup_interface(hapd_iface)) {
                                hostapd_deinit_driver(