RDKBWIFI-498: Fix EM subdoc memory leaks in webconfig decode and EM a…#1250
Open
dkyncu wants to merge 1 commit into
Open
RDKBWIFI-498: Fix EM subdoc memory leaks in webconfig decode and EM a…#1250dkyncu wants to merge 1 commit into
dkyncu wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes memory leaks in the EasyMesh AP metrics reporting pipeline by ensuring both decoded (cJSON tree + per-VAP arrays) and encoded (JSON string) allocations are freed across success/error paths.
Changes:
- Free parsed cJSON (
u.encoded.json) indecode_em_ap_metrics_report_subdoc()on success and additional error paths. - Free per-VAP decoded allocations (
sta_traffic_stats,sta_link_metrics) after translation inwebconfig_easymesh_decode()(EM_APP). - Free encoded payload strings (
u.encoded.raw) and missing success-path allocations in EasyMesh publishers inwifi_em.c.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| source/webconfig/wifi_webconfig_em_ap_metrics_report.c | Deletes decoded cJSON tree to stop per-interval subdoc decode leaks. |
| source/webconfig/wifi_easymesh_translator.c | Adds EM_APP cleanup for decoded per-VAP arrays after translation. |
| source/apps/em/wifi_em.c | Frees encoded JSON strings (and one missing struct free) in multiple EM publishers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…pp publishers The EasyMesh AP metrics pipeline leaks on both ends of the webconfig subdoc exchange, growing the consumer of the report (EM agent, via libwifi_webconfig) and OneWifi itself on every reporting interval. Leaks were located with LeakSanitizer and validated fixed on a device (RSS flat over 8 hours). Decode side (libwifi_webconfig): - decode_em_ap_metrics_report_subdoc never freed data->u.encoded.json; per framework convention (see decode_radio_subdoc) the subdoc decoder owns the parsed tree, so the whole cJSON tree of every report leaked. Delete it on the success path and on the two error paths that were missing it. - decode_em_ap_metrics_report_object mallocs per-vap sta_traffic_stats and sta_link_metrics arrays into the decoded params, but nothing on the decode/translate path freed them (webconfig_data_free only frees u.encoded.raw). Free them in webconfig_easymesh_decode after translation, mirroring the existing assoc-map cleanup. EM app publishers (wifi_em.c): - All four publishers (AP metrics report, sta link metrics report, channel scan report, beacon report) leaked the encoded JSON string: webconfig_encode allocates data->u.encoded.raw, the bus publish copies the payload, and the cleanup paths freed the decoded members and `data` but never the encoded string. The beacon report publisher also leaked wb_data itself on the success path. Signed-off-by: Durmus Koyuncu <durmus.kyncu.kd@gmail.com>
Author
|
Please review, thanks |
Nikita-Hakai
reviewed
Jul 7, 2026
| *type = webconfig_easymesh_data.type; | ||
| //debug_external_protos(&webconfig_easymesh_data, __func__, __LINE__); | ||
| #ifdef EM_APP | ||
| webconfig_easymesh_free_ap_metrics_report(&webconfig_easymesh_data); |
Contributor
There was a problem hiding this comment.
Do you think instead of this, we can cleanup in the corresponding translation function itself, something as below:
diff --git a/source/webconfig/wifi_easymesh_translator.c b/source/webconfig/wifi_easymesh_translator.c
index 5bc7ea4..fd717d1 100644
--- a/source/webconfig/wifi_easymesh_translator.c
+++ b/source/webconfig/wifi_easymesh_translator.c
@@ -1536,6 +1536,8 @@ webconfig_error_t translate_sta_link_metrics_object_to_easy_mesh_sta_info(webcon
if (sta_size == 0) {
wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d Dev Stats is NULL\n", __func__, __LINE__);
+ free(params->em_sta_link_metrics_rsp.per_sta_metrics);
+ params->em_sta_link_metrics_rsp.per_sta_metrics = NULL;
return webconfig_error_translate_to_easymesh;
}
@@ -1546,6 +1548,8 @@ webconfig_error_t translate_sta_link_metrics_object_to_easy_mesh_sta_info(webcon
proto = (webconfig_external_easymesh_t *)params->external_protos;
if (proto == NULL) {
wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: em_sta_info_t is NULL\n", __func__, __LINE__);
+ free(params->em_sta_link_metrics_rsp.per_sta_metrics);
+ params->em_sta_link_metrics_rsp.per_sta_metrics = NULL;
return webconfig_error_translate_to_easymesh;
}
@@ -1581,6 +1585,13 @@ webconfig_error_t translate_sta_link_metrics_object_to_easy_mesh_sta_info(webcon
proto->put_sta_info(proto->data_model, em_sta_dev_info, em_target_sta_map_assoc);
}
}
+
+ // Free the heap array allocated by decode_em_sta_link_metrics_object.
+ if (params->em_sta_link_metrics_rsp.per_sta_metrics != NULL) {
+ free(params->em_sta_link_metrics_rsp.per_sta_metrics);
+ params->em_sta_link_metrics_rsp.per_sta_metrics = NULL;
+ }
+
return webconfig_error_none;
}
@@ -1611,17 +1622,17 @@ webconfig_error_t translate_ap_metrics_report_to_easy_mesh_bss_info(webconfig_su
proto = (webconfig_external_easymesh_t *)data->u.decoded.external_protos;
if (proto == NULL) {
wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: external_protos is NULL\n", __func__, __LINE__);
- return webconfig_error_translate_to_easymesh;
+ goto cleanup_ap_metrics;
}
if (proto->get_radio_info(proto->data_model, 0) == NULL) {
wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: get_radio_info is NULL\n", __func__, __LINE__);
- return webconfig_error_translate_to_easymesh;
+ goto cleanup_ap_metrics;
}
if ((decoded_params->num_radios < MIN_NUM_RADIOS) || (decoded_params->num_radios > MAX_NUM_RADIOS )){
wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Invalid number of radios : %x\n", __func__, __LINE__
, decoded_params->num_radios);
- return webconfig_error_translate_to_easymesh;
+ goto cleanup_ap_metrics;
}
em_ap_report = &decoded_params->em_ap_metrics_report;
@@ -1752,7 +1763,27 @@ webconfig_error_t translate_ap_metrics_report_to_easy_mesh_bss_info(webconfig_su
}
}
- return webconfig_error_none;
+cleanup_ap_metrics:
+ // Free heap allocations made by decode_em_ap_metrics_report_object for
+ // sta_traffic_stats and sta_link_metrics <E2><80><94> these are only needed during
+ // translation and must be freed here once consumed, including on error paths.
+ if (em_ap_report != NULL) {
+ for (unsigned int i = 0; i < em_ap_report->radio_count; i++) {
+ for (int k = 0; k < MAX_NUM_VAP_PER_RADIO; k++) {
+ em_vap_metrics_t *vap_m = &em_ap_report->radio_reports[i].vap_reports[k];
+ if (vap_m->sta_traffic_stats != NULL) {
+ free(vap_m->sta_traffic_stats);
+ vap_m->sta_traffic_stats = NULL;
+ }
+ if (vap_m->sta_link_metrics != NULL) {
+ free(vap_m->sta_link_metrics);
+ vap_m->sta_link_metrics = NULL;
+ }
+ }
+ }
+ }
+
+ return (em_ap_report != NULL) ? webconfig_error_none : webconfig_error_translate_to_easymesh;
}
#endif
Contributor
There was a problem hiding this comment.
If its urgent to be merged, we can bring this change as a seperate PR too!
narendradandu
approved these changes
Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…pp publishers
The EasyMesh AP metrics pipeline leaks on both ends of the webconfig subdoc exchange, growing the consumer of the report (EM agent, via libwifi_webconfig) and OneWifi itself on every reporting interval. Leaks were located with LeakSanitizer and validated fixed on a device (RSS flat over 8 hours).
Decode side (libwifi_webconfig):
decode_em_ap_metrics_report_subdoc never freed data->u.encoded.json; per framework convention (see decode_radio_subdoc) the subdoc decoder owns the parsed tree, so the whole cJSON tree of every report leaked. Delete it on the success path and on the two error paths that were missing it.
decode_em_ap_metrics_report_object mallocs per-vap sta_traffic_stats and sta_link_metrics arrays into the decoded params, but nothing on the decode/translate path freed them (webconfig_data_free only frees u.encoded.raw). Free them in webconfig_easymesh_decode after translation, mirroring the existing assoc-map cleanup.
EM app publishers (wifi_em.c):
databut never the encoded string. The beacon report publisher also leaked wb_data itself on the success path.