Fix use after free warning introduced by gcc 12.1

gcc 12.1 complains about using pointer after realloc as it could
potentially be moved/freed, causing any uses after UB.

Fix this by doing checks before realloc and use those statuses and
update with new BSS.

Signed-off-by: Krishna T <krishna.t@nordicsemi.no>
This commit is contained in:
krishna T 2023-04-21 00:58:21 +05:30 committed by Jouni Malinen
parent 236c0cfbcd
commit 5025047ac3

View file

@ -183,9 +183,8 @@ static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
} }
static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s, static struct wpa_connect_work *
struct wpa_bss *old_bss, wpa_bss_check_pending_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
struct wpa_bss *new_bss)
{ {
struct wpa_radio_work *work; struct wpa_radio_work *work;
struct wpa_connect_work *cwork; struct wpa_connect_work *cwork;
@ -194,12 +193,19 @@ static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s,
if (!work) if (!work)
work = radio_work_pending(wpa_s, "connect"); work = radio_work_pending(wpa_s, "connect");
if (!work) if (!work)
return; return NULL;
cwork = work->ctx; cwork = work->ctx;
if (cwork->bss != old_bss) if (cwork->bss != bss)
return; return NULL;
return cwork;
}
static void wpa_bss_update_pending_connect(struct wpa_connect_work *cwork,
struct wpa_bss *new_bss)
{
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Update BSS pointer for the pending connect radio work"); "Update BSS pointer for the pending connect radio work");
cwork->bss = new_bss; cwork->bss = new_bss;
@ -211,6 +217,8 @@ static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s,
void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
const char *reason) const char *reason)
{ {
struct wpa_connect_work *cwork;
if (wpa_s->last_scan_res) { if (wpa_s->last_scan_res) {
unsigned int i; unsigned int i;
for (i = 0; i < wpa_s->last_scan_res_used; i++) { for (i = 0; i < wpa_s->last_scan_res_used; i++) {
@ -224,7 +232,9 @@ void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
} }
} }
} }
wpa_bss_update_pending_connect(wpa_s, bss, NULL); cwork = wpa_bss_check_pending_connect(wpa_s, bss);
if (cwork)
wpa_bss_update_pending_connect(cwork, NULL);
dl_list_del(&bss->list); dl_list_del(&bss->list);
dl_list_del(&bss->list_id); dl_list_del(&bss->list_id);
wpa_s->num_bss--; wpa_s->num_bss--;
@ -728,25 +738,34 @@ wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
} else { } else {
struct wpa_bss *nbss; struct wpa_bss *nbss;
struct dl_list *prev = bss->list_id.prev; struct dl_list *prev = bss->list_id.prev;
struct wpa_connect_work *cwork;
unsigned int i;
bool update_current_bss = wpa_s->current_bss == bss;
bool update_ml_probe_bss = wpa_s->ml_connect_probe_bss == bss;
cwork = wpa_bss_check_pending_connect(wpa_s, bss);
for (i = 0; i < wpa_s->last_scan_res_used; i++) {
if (wpa_s->last_scan_res[i] == bss)
break;
}
dl_list_del(&bss->list_id); dl_list_del(&bss->list_id);
nbss = os_realloc(bss, sizeof(*bss) + res->ie_len + nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
res->beacon_ie_len); res->beacon_ie_len);
if (nbss) { if (nbss) {
unsigned int i; if (i != wpa_s->last_scan_res_used)
for (i = 0; i < wpa_s->last_scan_res_used; i++) { wpa_s->last_scan_res[i] = nbss;
if (wpa_s->last_scan_res[i] == bss) {
wpa_s->last_scan_res[i] = nbss;
break;
}
}
if (wpa_s->current_bss == bss) if (update_current_bss)
wpa_s->current_bss = nbss; wpa_s->current_bss = nbss;
if (wpa_s->ml_connect_probe_bss == bss) if (update_ml_probe_bss)
wpa_s->ml_connect_probe_bss = nbss; wpa_s->ml_connect_probe_bss = nbss;
wpa_bss_update_pending_connect(wpa_s, bss, nbss); if (cwork)
wpa_bss_update_pending_connect(cwork, nbss);
bss = nbss; bss = nbss;
os_memcpy(bss->ies, res + 1, os_memcpy(bss->ies, res + 1,
res->ie_len + res->beacon_ie_len); res->ie_len + res->beacon_ie_len);