src: add safe_strtoull for safe string to number conversion

Add safe_strtoull to validate the execution of strtoull.
Definining the base of the number is required becase partition
codes are base 16 but they lack the 0x prefix.

Replace uses of atoi and strtoull/strtoul and log the conversion
errors.
master
Alejandro Sirgo Rica 2024-10-25 11:53:22 +02:00
parent e960063a13
commit e679925bd0
5 changed files with 74 additions and 6 deletions

View File

@ -14,6 +14,7 @@
#include "list.h"
#include "rest.h"
#include "json.h"
#include <stdint.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
@ -557,6 +558,7 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
int disk_part_len = 0;
char disk_part[1024];
const char *msglog;
uint64_t part_code;
int i;
if (serial_number && strlen(serial_number) > 0) {
@ -617,7 +619,12 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
continue;
}
reported_disk.size = strtoull(disks[i].size, NULL, 0);
if (safe_strtoull(disks[i].size, &reported_disk.size, 10, UINT64_MAX) < 0) {
syslog(LOG_ERR, "failed to parse disk size for disk %d (%s:%d)\n",
i + 1, __func__, __LINE__);
return false;
}
cur_disk.size = dbi_result_get_longlong(result, "tamano");
dbi_result_free(result);
@ -661,8 +668,17 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
return false;
}
reported_part.size = strtoull(partitions[i].size, NULL, 0);
reported_part.code = strtoul(partitions[i].code, NULL, 16);
if (safe_strtoull(partitions[i].size, &reported_part.size, 10, UINT64_MAX) < 0) {
syslog(LOG_ERR, "failed to parse partition size %s for partition %d (%s:%d)\n",
partitions[i].size, i + 1, __func__, __LINE__);
return false;
}
if (safe_strtoull(partitions[i].code, &part_code, 32, UINT32_MAX) < 0) {
syslog(LOG_ERR, "failed to parse partition code %s for partition %d (%s:%d)\n",
partitions[i].code, i + 1, __func__, __LINE__);
return false;
}
reported_part.code = part_code;
reported_part.filesystem = get_filesystem_id(partitions[i].filesystem);
reported_part.used_size = partitions[i].used_size;
reported_part.free_size = partitions[i].free_size;

View File

@ -367,6 +367,7 @@ void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io, int events)
int og_socket_server_init(const char *addr, const char *port)
{
struct sockaddr_in local;
uint64_t port_num;
uint32_t s_addr;
int sd, on = 1;
@ -384,7 +385,13 @@ int og_socket_server_init(const char *addr, const char *port)
local.sin_addr.s_addr = s_addr;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(port));
if (safe_strtoull(port, &port_num, 10, UINT16_MAX) < 0) {
syslog(LOG_ERR, "failed to parse port %s (%s:%d)\n",
port, __func__, __LINE__);
return -1;
}
local.sin_port = htons(port_num);
if (bind(sd, (struct sockaddr *) &local, sizeof(local)) < 0) {
close(sd);

View File

@ -520,6 +520,7 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params)
const char *msglog;
struct og_dbi *dbi;
int err = 0, i = 0;
uint64_t wol_type;
dbi_result result;
const char *key;
json_t *value;
@ -621,8 +622,14 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params)
if (!inet_aton(new_params.netmask_array[i], &netmask))
continue;
if (safe_strtoull(params->wol_type, &wol_type, 10, UINT32_MAX) < 0) {
syslog(LOG_ERR, "failed to parse wol type %s (%s:%d)\n",
params->wol_type, __func__, __LINE__);
continue;
}
if (wake_up(sd, &addr, &netmask, new_params.mac_array[i],
atoi(params->wol_type)) < 0) {
wol_type) < 0) {
syslog(LOG_ERR, "Failed to send wol packet to %s\n",
new_params.ips_array[i]);
continue;
@ -3845,6 +3852,7 @@ static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
static int og_cmd_delete_image(json_t *element, struct og_msg_params *params)
{
struct og_dbi *dbi;
uint64_t image_id;
const char *key;
json_t *value;
int err = 0;
@ -3865,6 +3873,12 @@ static int og_cmd_delete_image(json_t *element, struct og_msg_params *params)
if (!og_msg_params_validate(params, OG_REST_PARAM_ID))
return -1;
if (safe_strtoull(params->id, &image_id, 10, UINT32_MAX) < 0) {
syslog(LOG_ERR, "failed to parse image id %s (%s:%d)\n",
params->id, __func__, __LINE__);
return -1;
}
dbi = og_dbi_open(&ogconfig.db);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
@ -3872,7 +3886,7 @@ static int og_cmd_delete_image(json_t *element, struct og_msg_params *params)
return -1;
}
err = og_dbi_delete_image(dbi, atoi(params->id));
err = og_dbi_delete_image(dbi, image_id);
if (err < 0) {
og_dbi_close(dbi);
return err;

View File

@ -7,7 +7,12 @@
* (at your option) any later version.
*/
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include "utils.h"
void str_toupper(char *str)
@ -29,3 +34,26 @@ void str_tolower(char *str)
c++;
}
}
int safe_strtoull(const char *str, uint64_t *out_value, int base, uint64_t max)
{
char *endptr = NULL;
uint64_t result;
errno = 0;
assert(str != NULL && out_value != NULL);
if (str[0] == '-')
return -1;
result = strtoull(str, &endptr, base);
if (endptr == str ||
*endptr != '\0' ||
(errno == ERANGE && result == ULLONG_MAX) ||
result > max)
return -1;
*out_value = result;
return 0;
}

View File

@ -1,7 +1,10 @@
#ifndef _OG_UTILS_H
#define _OG_UTILS_H
#include <stdint.h>
void str_toupper(char *str);
void str_tolower(char *str);
int safe_strtoull(const char *str, uint64_t *out_value, int base, uint64_t max);
#endif