AP MLD: Handle garbage pointer after MLD interface is deleted
In function driver_nl80211_link_remove(), when there is no active links, interface is removed. This will free the BSS pointer. A copy of the BSS pointer is also stored in each of the affiliated links' hapd->drv_priv member. driver_nl80211_link_remove() is called via multiple paths, e.g., via NL80211_CMD_STOP_AP and via driver_nl80211_ops. When called when handling an nl80211 event, links will be removed and when count reaches zero, the interface will be removed. However, core hostapd will be unaware of this removal. Hence, if it tries to access its drv_priv pointer, this can lead to segmentation fault at times since the pointer is now pointing to freed memory. Prevent this by adding a new notification event (EVENT_MLD_INTERFACE_FREED). Whenever the interface is freed, this notification will be sent. hostapd will process this notification and will set all affliated links' hapd->drv_priv to NULL. Signed-off-by: Naveen S <quic_naves@quicinc.com> Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
This commit is contained in:
parent
e1bf37022e
commit
c6ff28cb63
6 changed files with 34 additions and 1 deletions
|
@ -2859,6 +2859,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|||
hostapd_event_color_change(hapd, true);
|
||||
break;
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
case EVENT_MLD_INTERFACE_FREED:
|
||||
wpa_printf(MSG_DEBUG, "MLD: Interface %s freed",
|
||||
hapd->conf->iface);
|
||||
hostapd_mld_interface_freed(hapd);
|
||||
break;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "Unknown event %d", event);
|
||||
break;
|
||||
|
|
|
@ -3402,6 +3402,7 @@ static void hostapd_cleanup_driver(const struct wpa_driver_ops *driver,
|
|||
driver->is_drv_shared &&
|
||||
!driver->is_drv_shared(drv_priv, iface->bss[0])) {
|
||||
driver->hapd_deinit(drv_priv);
|
||||
hostapd_mld_interface_freed(iface->bss[0]);
|
||||
} else if (hostapd_if_link_remove(iface->bss[0],
|
||||
WPA_IF_AP_BSS,
|
||||
iface->bss[0]->conf->iface,
|
||||
|
@ -4981,6 +4982,18 @@ struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd)
|
|||
return mld->fbss;
|
||||
}
|
||||
|
||||
|
||||
void hostapd_mld_interface_freed(struct hostapd_data *hapd)
|
||||
{
|
||||
struct hostapd_data *link_bss = NULL;
|
||||
|
||||
if (!hapd || !hapd->conf->mld_ap)
|
||||
return;
|
||||
|
||||
for_each_mld_link(link_bss, hapd)
|
||||
link_bss->drv_priv = NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
|
||||
|
|
|
@ -852,6 +852,7 @@ int hostapd_fill_cca_settings(struct hostapd_data *hapd,
|
|||
#ifdef CONFIG_IEEE80211BE
|
||||
|
||||
bool hostapd_mld_is_first_bss(struct hostapd_data *hapd);
|
||||
void hostapd_mld_interface_freed(struct hostapd_data *hapd);
|
||||
|
||||
#define for_each_mld_link(partner, self) \
|
||||
dl_list_for_each(partner, &self->mld->links, struct hostapd_data, link)
|
||||
|
|
|
@ -5847,6 +5847,11 @@ enum wpa_event_type {
|
|||
* EVENT_LINK_RECONFIG - Notification that AP links removed
|
||||
*/
|
||||
EVENT_LINK_RECONFIG,
|
||||
|
||||
/**
|
||||
* EVENT_MLD_INTERFACE_FREED - Notification of AP MLD interface removal
|
||||
*/
|
||||
EVENT_MLD_INTERFACE_FREED,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ const char * event_to_string(enum wpa_event_type event)
|
|||
E2S(LINK_CH_SWITCH_STARTED);
|
||||
E2S(TID_LINK_MAP);
|
||||
E2S(LINK_RECONFIG);
|
||||
E2S(MLD_INTERFACE_FREED);
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
|
|
|
@ -10765,6 +10765,7 @@ static int driver_nl80211_link_remove(void *priv, enum wpa_driver_if_type type,
|
|||
{
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
int ret;
|
||||
|
||||
if (type != WPA_IF_AP_BSS ||
|
||||
!nl80211_link_valid(bss->valid_links, link_id))
|
||||
|
@ -10784,7 +10785,12 @@ static int driver_nl80211_link_remove(void *priv, enum wpa_driver_if_type type,
|
|||
if (!bss->valid_links) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: No more links remaining, so remove interface");
|
||||
return wpa_driver_nl80211_if_remove(bss, type, ifname);
|
||||
ret = wpa_driver_nl80211_if_remove(bss, type, ifname);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Notify that the MLD interface is removed */
|
||||
wpa_supplicant_event(bss->ctx, EVENT_MLD_INTERFACE_FREED, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue