[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251117184409.42831-5-wander@redhat.com>
Date: Mon, 17 Nov 2025 15:41:11 -0300
From: Wander Lairson Costa <wander@...hat.com>
To: Steven Rostedt <rostedt@...dmis.org>,
Wander Lairson Costa <wander@...hat.com>,
Tomas Glozar <tglozar@...hat.com>,
Ivan Pravdin <ipravdin.official@...il.com>,
Crystal Wood <crwood@...hat.com>,
John Kacur <jkacur@...hat.com>,
Costa Shulyupin <costa.shul@...hat.com>,
Tiezhu Yang <yangtiezhu@...ngson.cn>,
linux-trace-kernel@...r.kernel.org (open list:Real-time Linux Analysis (RTLA) tools),
linux-kernel@...r.kernel.org (open list),
bpf@...r.kernel.org (open list:BPF [MISC]:Keyword:(?:\b|_)bpf(?:\b|_))
Subject: [rtla 04/13] rtla: Replace atoi() with a robust strtoi()
The atoi() function does not perform error checking, which can lead to
undefined behavior when parsing invalid or out-of-range strings. This
can cause issues when parsing user-provided numerical inputs, such as
signal numbers, PIDs, or CPU lists.
To address this, introduce a new strtoi() helper function that safely
converts a string to an integer. This function validates the input and
checks for overflows, returning a boolean to indicate success or failure.
Replace all calls to atoi() with the new strtoi() function and add
proper error handling to make the parsing more robust and prevent
potential issues.
Signed-off-by: Wander Lairson Costa <wander@...hat.com>
---
tools/tracing/rtla/src/actions.c | 6 +++--
tools/tracing/rtla/src/utils.c | 40 ++++++++++++++++++++++++++++----
tools/tracing/rtla/src/utils.h | 2 ++
3 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index efa17290926da..e23d4f1c5a592 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -199,12 +199,14 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
/* Takes two arguments, num (signal) and pid */
while (token != NULL) {
if (strlen(token) > 4 && strncmp(token, "num=", 4) == 0) {
- signal = atoi(token + 4);
+ if(!strtoi(token + 4, &signal))
+ return -1;
} else if (strlen(token) > 4 && strncmp(token, "pid=", 4) == 0) {
if (strncmp(token + 4, "parent", 7) == 0)
pid = -1;
else
- pid = atoi(token + 4);
+ if (!strtoi(token + 4, &pid))
+ return -1;
} else {
/* Invalid argument */
return -1;
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index d6ab15dcb4907..4cb765b94feec 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
+#include <limits.h>
#include "utils.h"
@@ -112,16 +113,18 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set)
nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (p = cpu_list; *p; ) {
- cpu = atoi(p);
- if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus)
+ if (!strtoi(p, &cpu))
+ goto err;
+ if (cpu < 0 || cpu >= nr_cpus)
goto err;
while (isdigit(*p))
p++;
if (*p == '-') {
p++;
- end_cpu = atoi(p);
- if (end_cpu < cpu || (!end_cpu && *p != '0') || end_cpu >= nr_cpus)
+ if (!strtoi(p, &end_cpu))
+ goto err;
+ if (end_cpu < cpu || end_cpu >= nr_cpus)
goto err;
while (isdigit(*p))
p++;
@@ -322,6 +325,7 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr)
struct dirent *proc_entry;
DIR *procfs;
int retval;
+ int pid;
if (strlen(comm_prefix) >= MAX_PATH) {
err_msg("Command prefix is too long: %d < strlen(%s)\n",
@@ -341,8 +345,12 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr)
if (!retval)
continue;
+ if (!strtoi(proc_entry->d_name, &pid)) {
+ err_msg("'%s' is not a valid pid", proc_entry->d_name);
+ goto out_err;
+ }
/* procfs_is_workload_pid confirmed it is a pid */
- retval = __set_sched_attr(atoi(proc_entry->d_name), attr);
+ retval = __set_sched_attr(pid, attr);
if (retval) {
err_msg("Error setting sched attributes for pid:%s\n", proc_entry->d_name);
goto out_err;
@@ -959,3 +967,25 @@ int auto_house_keeping(cpu_set_t *monitored_cpus)
return 1;
}
+
+/*
+ * strtoi - convert string to integer with error checking
+ *
+ * Returns true on success, false if conversion fails or result is out of int range.
+ */
+bool strtoi(const char *s, int *res)
+{
+ char *end_ptr;
+ long lres;
+
+ if (!*s)
+ return false;
+
+ errno = 0;
+ lres = strtol(s, &end_ptr, 0);
+ if (errno || *end_ptr || lres > INT_MAX || lres < INT_MIN)
+ return false;
+
+ *res = (int) lres;
+ return true;
+}
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index a2a6f89f342d0..160491f5de91c 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <time.h>
#include <sched.h>
+#include <stdbool.h>
/*
* '18446744073709551615\0'
@@ -80,6 +81,7 @@ static inline int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int stat
static inline int have_libcpupower_support(void) { return 0; }
#endif /* HAVE_LIBCPUPOWER_SUPPORT */
int auto_house_keeping(cpu_set_t *monitored_cpus);
+bool strtoi(const char *s, int *res);
#define ns_to_usf(x) (((double)x/1000))
#define ns_to_per(total, part) ((part * 100) / (double)total)
--
2.51.1
Powered by blists - more mailing lists