Browse Source

hostapd: get reference to object before removal

`ucv_array_set` releases the array's reference to the object being cleared.
If this is the last reference to the object, it will be freed, making our
pointer `val` invalid.

To avoid this, we need to obtain our own reference to the object so we
can safely return `val`.

Signed-off-by: Matthew Cather <[email protected]>
(cherry picked from commit 6a10da2934441a59283394a84917edf4983e3043)
Matthew Cather 1 year ago
parent
commit
634ac2bab7

+ 3 - 1
package/network/services/hostapd/src/src/ap/ucode.c

@@ -876,7 +876,7 @@ void hostapd_ucode_free(void)
 
 void hostapd_ucode_free_iface(struct hostapd_iface *iface)
 {
-	wpa_ucode_registry_remove(iface_registry, iface->ucode.idx);
+	ucv_put(wpa_ucode_registry_remove(iface_registry, iface->ucode.idx));
 }
 
 void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
@@ -910,6 +910,8 @@ void hostapd_ucode_free_bss(struct hostapd_data *hapd)
 	uc_value_push(ucv_string_new(hapd->conf->iface));
 	uc_value_push(ucv_get(val));
 	ucv_put(wpa_ucode_call(2));
+
+	ucv_put(val);
 	ucv_gc(vm);
 }
 

+ 1 - 0
package/network/services/hostapd/src/src/utils/ucode.c

@@ -470,6 +470,7 @@ uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx)
 	if (!val)
 		return NULL;
 
+	ucv_get(val);
 	ucv_array_set(reg, idx - 1, NULL);
 	dataptr = ucv_resource_dataptr(val, NULL);
 	if (dataptr)

+ 1 - 0
package/network/services/hostapd/src/wpa_supplicant/ucode.c

@@ -70,6 +70,7 @@ void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s)
 	uc_value_push(ucv_string_new(wpa_s->ifname));
 	uc_value_push(ucv_get(val));
 	ucv_put(wpa_ucode_call(2));
+	ucv_put(val);
 	ucv_gc(vm);
 }