]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix use after free warning introduced by gcc 12.1
authorkrishna T <krishna.t@nordicsemi.no>
Thu, 20 Apr 2023 19:28:21 +0000 (00:58 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 6 Nov 2023 08:57:34 +0000 (10:57 +0200)
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>
wpa_supplicant/bss.c

index 5ada34c4f49d5fffecf881e1d72a4d019ca231aa..2ad74f3a4b4eadd2c895492e25efaf0c0b9b4d9d 100644 (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);