From f8eca04841725180fc78a1dd8bbf6435e02d554a Mon Sep 17 00:00:00 2001 From: OpenGnSys Support Team Date: Thu, 23 Nov 2023 21:22:11 +0100 Subject: rest: fix WoL handling Valgrind reports a memleak because og_cmd_wol() overrides params->ips_array, then it releases params->ips_array but og_cmd_free() already does this. Use a new_params structure to store the IPs that has been filtered through the database query and check that buffer overrun does not happen. Fixes: e4cb91b5f660 ("#990 wol: migrate mac and netmask query to ogServer") --- src/rest.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/rest.c b/src/rest.c index 51fb322..b58b468 100644 --- a/src/rest.c +++ b/src/rest.c @@ -568,6 +568,7 @@ struct og_client_wol *og_client_wol_find(const struct in_addr *addr) static int og_cmd_wol(json_t *element, struct og_msg_params *params) { char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {}; + struct og_msg_params new_params = {}; struct og_client_wol *cli_wol; struct in_addr addr, netmask; int ips_str_len = 0; @@ -627,10 +628,18 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params) } for (i = 0; dbi_result_next_row(result); i++) { - params->ips_array[i] = dbi_result_get_string_copy(result, "ip"); - params->mac_array[i] = dbi_result_get_string_copy(result, "mac"); - params->netmask_array[i] = dbi_result_get_string_copy(result, "netmask"); + if (i >= OG_CLIENTS_MAX) { + syslog(LOG_ERR, "too many IPs in WoL (%s:%d)\n", + __func__, __LINE__); + dbi_result_free(result); + og_dbi_close(dbi); + goto err_free_params; + } + new_params.ips_array[i] = dbi_result_get_string_copy(result, "ip"); + new_params.mac_array[i] = dbi_result_get_string_copy(result, "mac"); + new_params.netmask_array[i] = dbi_result_get_string_copy(result, "netmask"); } + new_params.ips_array_len = i; dbi_result_free(result); og_dbi_close(dbi); @@ -645,11 +654,11 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params) goto err_free_params; } - for (i = 0; i < params->ips_array_len; i++) { - if (og_client_find(params->ips_array[i])) + for (i = 0; i < new_params.ips_array_len; i++) { + if (og_client_find(new_params.ips_array[i])) continue; - if (inet_aton(params->ips_array[i], &addr) < 0) + if (inet_aton(new_params.ips_array[i], &addr) < 0) continue; cli_wol = og_client_wol_find(&addr); @@ -664,23 +673,23 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params) list_add_tail(&cli_wol->list, &client_wol_list); - if (inet_aton(params->netmask_array[i], &netmask) < 0) + if (inet_aton(new_params.netmask_array[i], &netmask) < 0) continue; - if (wake_up(sd, &addr, &netmask, params->mac_array[i], + if (wake_up(sd, &addr, &netmask, new_params.mac_array[i], atoi(params->wol_type)) < 0) { syslog(LOG_ERR, "Failed to send wol packet to %s\n", - params->ips_array[i]); + new_params.ips_array[i]); continue; } } err_out: close(sd); err_free_params: - for (i = 0; i < params->ips_array_len; ++i) { - free((void *)params->ips_array[i]); - free((void *)params->mac_array[i]); - free((void *)params->netmask_array[i]); + for (i = 0; i < new_params.ips_array_len; ++i) { + free((void *)new_params.ips_array[i]); + free((void *)new_params.mac_array[i]); + free((void *)new_params.netmask_array[i]); } return 0; -- cgit v1.2.3-18-g5258