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,
struct wpa_bss *old_bss,
struct wpa_bss *new_bss)
static struct wpa_connect_work *
wpa_bss_check_pending_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
{
struct wpa_radio_work *work;
struct wpa_connect_work *cwork;
@ -194,12 +193,19 @@ static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s,
if (!work)
work = radio_work_pending(wpa_s, "connect");
if (!work)
return;
return NULL;
cwork = work->ctx;
if (cwork->bss != old_bss)
return;
if (cwork->bss != bss)
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,
"Update BSS pointer for the pending connect radio work");
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,
const char *reason)
{
struct wpa_connect_work *cwork;
if (wpa_s->last_scan_res) {
unsigned int 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_id);
wpa_s->num_bss--;
@ -728,25 +738,34 @@ wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
} else {
struct wpa_bss *nbss;
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);
nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
res->beacon_ie_len);
if (nbss) {
unsigned int i;
for (i = 0; i < wpa_s->last_scan_res_used; i++) {
if (wpa_s->last_scan_res[i] == bss) {
wpa_s->last_scan_res[i] = nbss;
break;
}
}
if (i != wpa_s->last_scan_res_used)
wpa_s->last_scan_res[i] = nbss;
if (wpa_s->current_bss == bss)
if (update_current_bss)
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_bss_update_pending_connect(wpa_s, bss, nbss);
if (cwork)
wpa_bss_update_pending_connect(cwork, nbss);
bss = nbss;
os_memcpy(bss->ies, res + 1,
res->ie_len + res->beacon_ie_len);