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: e4cb91b5f6 ("#990 wol: migrate mac and netmask query to ogServer")
master
OpenGnSys Support Team 2023-11-23 21:22:11 +01:00
parent 2140012535
commit f8eca04841
1 changed files with 22 additions and 13 deletions

View File

@ -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;