hostapd: consistent reference counting for registry
authorMatthew Cather <mattbob4@gmail.com>
Mon, 3 Mar 2025 20:00:35 +0000 (14:00 -0600)
committerFelix Fietkau <nbd@nbd.name>
Wed, 5 Mar 2025 07:03:00 +0000 (08:03 +0100)
Since `wpa_ucode_registry_add` collects its own reference to the values added, the
two functions `hostapd_ucode_bss_get_uval` and `hostapd_ucode_iface_get_uval` would
sometimes return a referenced object (from `uc_resource_new`) and sometimes return
an unreferenced object (from `wpa_ucode_registry_get`). Now, both functions always
return a referenced object.

This change also indirectly fixes `hostapd_ucode_bss_get_uval`, ensuring it now
always returns a referenced object.

Signed-off-by: Matthew Cather <mattbob4@gmail.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/network/services/hostapd/src/src/ap/ucode.c
package/network/services/hostapd/src/wpa_supplicant/ucode.c

index ff2d3ab55719e2738189c9db6e58530041b04e81..74e5558626dd50fe84631e4fe4d87ebeeba1b3f8 100644 (file)
@@ -23,7 +23,7 @@ hostapd_ucode_bss_get_uval(struct hostapd_data *hapd)
        uc_value_t *val;
 
        if (hapd->ucode.idx)
-               return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx);
+               return ucv_get(wpa_ucode_registry_get(bss_registry, hapd->ucode.idx));
 
        val = uc_resource_new(bss_type, hapd);
        hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val);
@@ -37,7 +37,7 @@ hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd)
        uc_value_t *val;
 
        if (hapd->ucode.idx)
-               return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx);
+               return ucv_get(wpa_ucode_registry_get(iface_registry, hapd->ucode.idx));
 
        val = uc_resource_new(iface_type, hapd);
        hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val);
@@ -54,10 +54,9 @@ hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, u
        list = ucv_array_new(vm);
        for (i = 0; iface->bss && i < iface->num_bss; i++) {
                struct hostapd_data *hapd = iface->bss[i];
-               uc_value_t *val = hostapd_ucode_bss_get_uval(hapd);
 
                ucv_array_set(list, i, ucv_string_new(hapd->conf->iface));
-               ucv_object_add(bss, hapd->conf->iface, ucv_get(val));
+               ucv_object_add(bss, hapd->conf->iface, hostapd_ucode_bss_get_uval(hapd));
        }
        ucv_object_add(if_bss, iface->phy, list);
 }
@@ -73,7 +72,7 @@ hostapd_ucode_update_interfaces(void)
        for (i = 0; i < interfaces->count; i++) {
                struct hostapd_iface *iface = interfaces->iface[i];
 
-               ucv_object_add(ifs, iface->phy, ucv_get(hostapd_ucode_iface_get_uval(iface)));
+               ucv_object_add(ifs, iface->phy, hostapd_ucode_iface_get_uval(iface));
                hostapd_ucode_update_bss_list(iface, if_bss, bss);
        }
 
@@ -932,6 +931,7 @@ void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
        uc_value_push(ucv_string_new(hapd->conf->iface));
        uc_value_push(ucv_get(val));
        ucv_put(wpa_ucode_call(3));
+       ucv_put(val);
        ucv_gc(vm);
 }
 
@@ -966,6 +966,7 @@ void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname)
        uc_value_push(ucv_get(val));
        uc_value_push(ucv_string_new(ifname)); // APuP peer ifname
        ucv_put(wpa_ucode_call(2));
+       ucv_put(val);
        ucv_gc(vm);
 }
 #endif // def CONFIG_APUP
index bef7552873e3272560affd4cd59219687501700d..506bde45c93d06ae397c7d7acd4ddb9815d09e4d 100644 (file)
@@ -20,7 +20,7 @@ wpas_ucode_iface_get_uval(struct wpa_supplicant *wpa_s)
        uc_value_t *val;
 
        if (wpa_s->ucode.idx)
-               return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx);
+               return ucv_get(wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx));
 
        val = uc_resource_new(iface_type, wpa_s);
        wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val);
@@ -36,7 +36,7 @@ wpas_ucode_update_interfaces(void)
        int i;
 
        for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next)
-               ucv_object_add(ifs, wpa_s->ifname, ucv_get(wpas_ucode_iface_get_uval(wpa_s)));
+               ucv_object_add(ifs, wpa_s->ifname, wpas_ucode_iface_get_uval(wpa_s));
 
        ucv_object_add(ucv_prototype_get(global), "interfaces", ifs);
        ucv_gc(vm);
@@ -50,7 +50,7 @@ void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s)
                return;
 
        uc_value_push(ucv_string_new(wpa_s->ifname));
-       uc_value_push(ucv_get(wpas_ucode_iface_get_uval(wpa_s)));
+       uc_value_push(wpas_ucode_iface_get_uval(wpa_s));
        ucv_put(wpa_ucode_call(2));
        ucv_gc(vm);
 }