WPS ER: Fix deinit timeout handling with delayed/failing unsubscribe
The five second timeout to call wps_er_deinit_finish() could potentially be left behind when removing the ER data based on some other event. This could result in double-freeing of wps_er context killing the process, e.g., if the WPS ER functionality is stopped while in the process of unsubscribing from an AP and then restarted. In addition, AP entries could still be present in the er->ap_unsubscribing list when the deinit timeout hits. These entries would still maintain HTTP context pointing to the ER which would be freed here and as such, the following HTTP client callback could refer to freed memory and kill the process. Fix this by freeing AP entries from ap_unsubscribing list when ER is deinitialized from timeout even if such AP entries have not completed unsubscription from UPnP events. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
7b75c30109
commit
c9629476f3
1 changed files with 11 additions and 3 deletions
|
@ -185,10 +185,8 @@ static void wps_er_ap_unsubscribed(struct wps_er *er, struct wps_er_ap *ap)
|
|||
dl_list_del(&ap->list);
|
||||
wps_er_ap_free(ap);
|
||||
|
||||
if (er->deinitializing && dl_list_empty(&er->ap_unsubscribing)) {
|
||||
eloop_cancel_timeout(wps_er_deinit_finish, er, NULL);
|
||||
if (er->deinitializing && dl_list_empty(&er->ap_unsubscribing))
|
||||
wps_er_deinit_finish(er, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1347,9 +1345,19 @@ static void wps_er_deinit_finish(void *eloop_data, void *user_ctx)
|
|||
struct wps_er *er = eloop_data;
|
||||
void (*deinit_done_cb)(void *ctx);
|
||||
void *deinit_done_ctx;
|
||||
struct wps_er_ap *ap, *tmp;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS ER: Finishing deinit");
|
||||
|
||||
dl_list_for_each_safe(ap, tmp, &er->ap_unsubscribing, struct wps_er_ap,
|
||||
list) {
|
||||
wpa_printf(MSG_DEBUG, "WPS ER: AP entry for %s (%s) still in ap_unsubscribing list - free it",
|
||||
inet_ntoa(ap->addr), ap->location);
|
||||
dl_list_del(&ap->list);
|
||||
wps_er_ap_free(ap);
|
||||
}
|
||||
|
||||
eloop_cancel_timeout(wps_er_deinit_finish, er, NULL);
|
||||
deinit_done_cb = er->deinit_done_cb;
|
||||
deinit_done_ctx = er->deinit_done_ctx;
|
||||
os_free(er->ip_addr_text);
|
||||
|
|
Loading…
Reference in a new issue