diff options
author | OpenGnSys Support Team <soporte-og@soleta.eu> | 2023-11-23 21:22:11 +0100 |
---|---|---|
committer | OpenGnSys Support Team <soporte-og@soleta.eu> | 2023-11-23 22:08:41 +0100 |
commit | f8eca04841725180fc78a1dd8bbf6435e02d554a (patch) | |
tree | 96971f93edfd5e07be0d46db3992588e17fd6b5a /src/rest.c | |
parent | 2140012535797296ae170c1d0595eacf126bc50d (diff) |
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")
Diffstat (limited to 'src/rest.c')
-rw-r--r-- | src/rest.c | 35 |
1 files changed, 22 insertions, 13 deletions
@@ -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; |