[openwrt/openwrt] hostapd: fix ucode memory leak with strings

LEDE Commits lede-commits at lists.infradead.org
Tue Mar 4 23:03:08 PST 2025


nbd pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/f79968ee0f76c41414fb0c08980b9c2a259964d3

commit f79968ee0f76c41414fb0c08980b9c2a259964d3
Author: Matthew Cather <mattbob4 at gmail.com>
AuthorDate: Mon Mar 3 13:22:11 2025 -0600

    hostapd: fix ucode memory leak with strings
    
    This fixes a common reference counting bug typically along the lines of:
    ```
    uc_value_push(ucv_get(ucv_string_new(...)));
    ```
    This would leave our new string with a reference count of 2, one from
    the construction of the string, the other from `ucv_get`. This would
    prevent the strings from being correctly cleaned up when it goes out
    of scope.
    
    Signed-off-by: Matthew Cather <mattbob4 at gmail.com>
---
 .../network/services/hostapd/src/src/ap/ucode.c    | 22 ++++++++++------------
 .../network/services/hostapd/src/src/utils/ucode.c |  2 +-
 .../services/hostapd/src/wpa_supplicant/ucode.c    | 17 ++++++++---------
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/package/network/services/hostapd/src/src/ap/ucode.c b/package/network/services/hostapd/src/src/ap/ucode.c
index e496b8b7aa..ede606b6b3 100644
--- a/package/network/services/hostapd/src/src/ap/ucode.c
+++ b/package/network/services/hostapd/src/src/ap/ucode.c
@@ -56,7 +56,7 @@ hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, u
 		struct hostapd_data *hapd = iface->bss[i];
 		uc_value_t *val = hostapd_ucode_bss_get_uval(hapd);
 
-		ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface)));
+		ucv_array_set(list, i, ucv_string_new(hapd->conf->iface));
 		ucv_object_add(bss, hapd->conf->iface, ucv_get(val));
 	}
 	ucv_object_add(if_bss, iface->phy, ucv_get(list));
@@ -721,11 +721,10 @@ int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta)
 	if (wpa_ucode_call_prepare("sta_auth"))
 		return 0;
 
-	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
+	uc_value_push(ucv_string_new(hapd->conf->iface));
 
 	snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr));
-	val = ucv_string_new(addr);
-	uc_value_push(ucv_get(val));
+	uc_value_push(ucv_string_new(addr));
 
 	val = wpa_ucode_call(2);
 
@@ -787,16 +786,15 @@ void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta
 	if (wpa_ucode_call_prepare("sta_connected"))
 		return;
 
-	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
+	uc_value_push(ucv_string_new(hapd->conf->iface));
 
 	snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr));
-	val = ucv_string_new(addr);
-	uc_value_push(ucv_get(val));
+	uc_value_push(ucv_string_new(addr));
 
 	val = ucv_object_new(vm);
 	if (sta->psk_idx)
 		ucv_object_add(val, "psk_idx", ucv_int64_new(sta->psk_idx - 1));
-	uc_value_push(ucv_get(val));
+	uc_value_push(val);
 
 	val = wpa_ucode_call(3);
 	if (ucv_type(val) != UC_OBJECT)
@@ -929,8 +927,8 @@ void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type)
 		return;
 
 	val = hostapd_ucode_bss_get_uval(hapd);
-	uc_value_push(ucv_get(ucv_string_new(hapd->iface->phy)));
-	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface)));
+	uc_value_push(ucv_string_new(hapd->iface->phy));
+	uc_value_push(ucv_string_new(hapd->conf->iface));
 	uc_value_push(ucv_get(val));
 	ucv_put(wpa_ucode_call(3));
 	ucv_gc(vm);
@@ -963,9 +961,9 @@ void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname)
 		return;
 
 	val = hostapd_ucode_bss_get_uval(hapd);
-	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); // BSS ifname
+	uc_value_push(ucv_string_new(hapd->conf->iface)); // BSS ifname
 	uc_value_push(ucv_get(val));
-	uc_value_push(ucv_get(ucv_string_new(ifname))); // APuP peer ifname
+	uc_value_push(ucv_string_new(ifname)); // APuP peer ifname
 	ucv_put(wpa_ucode_call(2));
 	ucv_gc(vm);
 }
diff --git a/package/network/services/hostapd/src/src/utils/ucode.c b/package/network/services/hostapd/src/src/utils/ucode.c
index a1762844b5..7ce121ee1e 100644
--- a/package/network/services/hostapd/src/src/utils/ucode.c
+++ b/package/network/services/hostapd/src/src/utils/ucode.c
@@ -172,7 +172,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs)
 	ucv_object_add(ret, "op_class", ucv_int64_new(op_class));
 	ucv_object_add(ret, "channel", ucv_int64_new(channel));
 	ucv_object_add(ret, "hw_mode", ucv_int64_new(hw_mode));
-	ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr)));
+	ucv_object_add(ret, "hw_mode_str", ucv_string_new(modestr));
 	ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel));
 	ucv_object_add(ret, "frequency", ucv_int64_new(freq_val));
 
diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c
index 9380b301c3..31427c39a1 100644
--- a/package/network/services/hostapd/src/wpa_supplicant/ucode.c
+++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.c
@@ -49,7 +49,7 @@ void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s)
 	if (wpa_ucode_call_prepare("iface_add"))
 		return;
 
-	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
+	uc_value_push(ucv_string_new(wpa_s->ifname));
 	uc_value_push(ucv_get(wpas_ucode_iface_get_uval(wpa_s)));
 	ucv_put(wpa_ucode_call(2));
 	ucv_gc(vm);
@@ -67,7 +67,7 @@ void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s)
 	if (wpa_ucode_call_prepare("iface_remove"))
 		return;
 
-	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
+	uc_value_push(ucv_string_new(wpa_s->ifname));
 	uc_value_push(ucv_get(val));
 	ucv_put(wpa_ucode_call(2));
 	ucv_gc(vm);
@@ -86,9 +86,9 @@ void wpas_ucode_update_state(struct wpa_supplicant *wpa_s)
 		return;
 
 	state = wpa_supplicant_state_txt(wpa_s->wpa_state);
-	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
+	uc_value_push(ucv_string_new(wpa_s->ifname));
 	uc_value_push(ucv_get(val));
-	uc_value_push(ucv_get(ucv_string_new(state)));
+	uc_value_push(ucv_string_new(state));
 	ucv_put(wpa_ucode_call(3));
 	ucv_gc(vm);
 }
@@ -108,9 +108,9 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d
 	if (wpa_ucode_call_prepare("event"))
 		return;
 
-	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
+	uc_value_push(ucv_string_new(wpa_s->ifname));
 	uc_value_push(ucv_get(val));
-	uc_value_push(ucv_get(ucv_string_new(event_to_string(event))));
+	uc_value_push(ucv_string_new(event_to_string(event)));
 	val = ucv_object_new(vm);
 	uc_value_push(ucv_get(val));
 
@@ -212,15 +212,14 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
 {
 	struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface");
 	struct wpa_bss *bss;
-	uc_value_t *ret, *val;
+	uc_value_t *ret;
 
 	if (!wpa_s)
 		return NULL;
 
 	ret = ucv_object_new(vm);
 
-	val = ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state));
-	ucv_object_add(ret, "state", ucv_get(val));
+	ucv_object_add(ret, "state", ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state)));
 
 	bss = wpa_s->current_bss;
 	if (bss) {




More information about the lede-commits mailing list