[PATCH stalld 41/52] stalld: fix signed integer overflow in set_reservation

Wander Lairson Costa <[email protected]> Mon, 8 Jun 2026 15:31:51 -0300
Newsgroups org.kernel.vger.linux-rt-users
Message-ID <[email protected]>
The deadline period calculation multiplies the period parameter by one
billion using int arithmetic. For period values of three or four the
product exceeds INT_MAX, triggering signed integer overflow and passing
a corrupt value to sched_setattr().

Switch the local variables to uint64_t, apply ULL suffixes so the
multiplication is performed in 64-bit arithmetic, change the function
parameters to unsigned int, and use PRIu64 in the log format string.

Signed-off-by: Wander Lairson Costa <[email protected]>
---
 src/stalld.h |  2 +-
 src/utils.c  | 11 ++++++-----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/stalld.h b/src/stalld.h
index b910870..81ce9f7 100644
--- a/src/stalld.h
+++ b/src/stalld.h
@@ -204,7 +204,7 @@ int rt_throttling_is_off(void);
 int turn_off_rt_throttling(void);
 void cleanup_regex(unsigned int *nr_task, regex_t **compiled_expr);
 void find_sched_debug_path(void);
-int set_reservation(int period, int reservation);
+int set_reservation(unsigned int period, unsigned int reservation);
 int get_tgid(int pid);
 void merge_tasks_info(int cpu, struct task_info *old_tasks, int nr_old, struct task_info *new_tasks, int nr_new);
 int set_cpu_affinity(char *cpu_list);
diff --git a/src/utils.c b/src/utils.c
index 5d54ae9..738d059 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -29,6 +29,7 @@
 #include <linux/sched.h>
 #include <sys/sysinfo.h>
 #include <mntent.h>
+#include <inttypes.h>
 
 #include "stalld.h"
 #include "sched_debug.h"
@@ -702,9 +703,9 @@ void write_pidfile(void)
  * picture, as at the end, the task will receive the % of time, while
  * avoiding have yet another knob to handle.
  */
-int set_reservation(int period, int reservation)
+int set_reservation(unsigned int period, unsigned int reservation)
 {
-	unsigned long dl_period, dl_runtime;
+	uint64_t dl_period, dl_runtime;
 	struct sched_attr attr;
 	int flags = 0;
 	int ret;
@@ -715,8 +716,8 @@ int set_reservation(int period, int reservation)
 	if (period > 4)
 		period = 1;
 
-	dl_period = period * 1000 * 1000 * 1000;
-	dl_runtime = dl_period * reservation / 100;
+	dl_period = period * 1000ULL * 1000ULL * 1000ULL;
+	dl_runtime = dl_period * reservation / 100ULL;
 
 	memset(&attr, 0, sizeof(attr));
 	attr.size = sizeof(attr);
@@ -731,7 +732,7 @@ int set_reservation(int period, int reservation)
 		return ret;
 	}
 
-	log_msg("successfully set %d%% SCHED_DEADLINE reservation runtime/period = %lld/%lld\n",
+	log_msg("successfully set %d%% SCHED_DEADLINE reservation runtime/period = %"PRIu64"/%"PRIu64"\n",
 		reservation, dl_runtime, dl_period);
 	return 0;
 }
-- 
2.54.0