summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlejandro Sirgo Rica <asirgo@soleta.eu>2024-10-25 11:53:22 +0200
committerAlejandro Sirgo Rica <asirgo@soleta.eu>2024-10-25 15:09:31 +0200
commite679925bd0c8608ebe24f34917347ad939c6506d (patch)
tree9076d0ff5d251bc0a0051589796b9f81cb86b11c /src
parente960063a137c8fe760a40a73ccd081e457b23952 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/client.c22
-rw-r--r--src/core.c9
-rw-r--r--src/rest.c18
-rw-r--r--src/utils.c28
-rw-r--r--src/utils.h3
5 files changed, 74 insertions, 6 deletions
diff --git a/src/client.c b/src/client.c
index bc66b4b..d1288c4 100644
--- a/src/client.c
+++ b/src/client.c
@@ -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;
diff --git a/src/core.c b/src/core.c
index 270bd9c..759e923 100644
--- a/src/core.c
+++ b/src/core.c
@@ -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);
diff --git a/src/rest.c b/src/rest.c
index f727322..167f88f 100644
--- a/src/rest.c
+++ b/src/rest.c
@@ -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;
diff --git a/src/utils.c b/src/utils.c
index d49a9ac..2607fc6 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -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;
+}
diff --git a/src/utils.h b/src/utils.h
index 45ecf23..288be67 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -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