From 5bac420e5e7059c6834bd6445afa6829103e0031 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 19 Oct 2021 00:04:46 +0300 Subject: [PATCH] DPP2: Clean up Controller on hostapd interface removal Stop the DPP Controller instance, if one is started, when the hostapd interface that was used to start that Controller is removed. This is needed to remove the control pointers that point to the soon-to-be-freed hostapd structures. This fixes an issue where a Controller operation with multiple interfaces could have resulted in references to freed memory if an interface is removed without explicitly stopping the DPP Controller. Signed-off-by: Jouni Malinen --- src/ap/dpp_hostapd.c | 2 ++ src/common/dpp.h | 1 + src/common/dpp_tcp.c | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 013022a87..41769f475 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -2276,6 +2276,8 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd) eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd, NULL); hostapd_dpp_chirp_stop(hapd); + if (hapd->iface->interfaces) + dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd); #endif /* CONFIG_DPP2 */ dpp_auth_deinit(hapd->dpp_auth); hapd->dpp_auth = NULL; diff --git a/src/common/dpp.h b/src/common/dpp.h index 75de3cae9..bc1cd4611 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -676,6 +676,7 @@ int dpp_relay_rx_gas_req(struct dpp_global *dpp, const u8 *src, const u8 *data, int dpp_controller_start(struct dpp_global *dpp, struct dpp_controller_config *config); void dpp_controller_stop(struct dpp_global *dpp); +void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx); struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp, unsigned int id); void dpp_controller_new_qr_code(struct dpp_global *dpp, diff --git a/src/common/dpp_tcp.c b/src/common/dpp_tcp.c index c373f1077..103eda272 100644 --- a/src/common/dpp_tcp.c +++ b/src/common/dpp_tcp.c @@ -1723,6 +1723,13 @@ void dpp_controller_stop(struct dpp_global *dpp) } +void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx) +{ + if (dpp && dpp->controller && dpp->controller->cb_ctx == cb_ctx) + dpp_controller_stop(dpp); +} + + static bool dpp_tcp_peer_id_match(struct dpp_authentication *auth, unsigned int id) {