Thread (65 messages) flat view 65 messages, 3 authors, 4d ago
COOLING4d

[PATCH 05/62] eal: validate memory size arguments

From: Stephen Hemminger <stephen@networkplumber.org>
Date: 2026-09-14 05:50:01
Subsystem: library code, the rest · Maintainers: Andrew Morton, Linus Torvalds

The -m, -n and -r options are converted with atoi(), which does not
detect any error: it returns zero for a string that is not a number at
all, and its behaviour on overflow is undefined.

So "-m foo" is silently taken as zero rather than rejected, and
"-m 99999999999999999999" is undefined. The -n and -r cases are partly
covered by their existing checks for zero, but only because a garbage
value happens to convert to zero; "-n 4x" is accepted as four.

The -m value is also scaled by 1024 * 1024 with no check, so a large
enough value wraps around and asks for a small amount of memory.

Use rte_kvargs_to_uint() for the three options, which converts the
whole string and checks it against a range. EAL already depends on
kvargs, so no new dependency is introduced. Note that this now bounds
-m so that the scaled value cannot overflow size_t, which on a 32-bit
build limits it to just under 4G; previously such a value was accepted
and wrapped.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/eal/common/eal_common_options.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index 42cdef632f..519307bdc3 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -9,6 +9,7 @@
 #include <ctype.h>
 #include <limits.h>
 #include <errno.h>
+#include <stdint.h>
 #include <getopt.h>
 #include <sys/queue.h>
 #ifndef RTE_EXEC_ENV_WINDOWS
@@ -29,6 +30,7 @@
 #include <rte_tailq.h>
 #include <rte_version.h>
 #include <rte_devargs.h>
+#include <rte_kvargs.h>
 #include <rte_memcpy.h>
 #ifndef RTE_EXEC_ENV_WINDOWS
 #include <rte_telemetry.h>
@@ -2210,23 +2212,34 @@ eal_parse_args(void)
 
 	/* memory options */
 	if (args.memory_size != NULL) {
-		int_cfg->memory = atoi(args.memory_size);
-		int_cfg->memory *= 1024ULL;
-		int_cfg->memory *= 1024ULL;
+		uint64_t mem;
+
+		/* value is in megabytes, and must not overflow when scaled */
+		if (rte_kvargs_to_uint(args.memory_size, 0,
+				       SIZE_MAX / (1024 * 1024), &mem) < 0) {
+			EAL_LOG(ERR, "invalid memory size parameter");
+			return -1;
+		}
+		int_cfg->memory = (size_t)mem * 1024 * 1024;
 	}
 	if (args.memory_channels != NULL) {
-		int_cfg->force_nchannel = atoi(args.memory_channels);
-		if (int_cfg->force_nchannel == 0) {
+		uint64_t channels;
+
+		if (rte_kvargs_to_uint(args.memory_channels, 1, UINT_MAX,
+				       &channels) < 0) {
 			EAL_LOG(ERR, "invalid memory channel parameter");
 			return -1;
 		}
+		int_cfg->force_nchannel = channels;
 	}
 	if (args.memory_ranks != NULL) {
-		int_cfg->force_nrank = atoi(args.memory_ranks);
-		if (int_cfg->force_nrank == 0 || int_cfg->force_nrank > 16) {
+		uint64_t ranks;
+
+		if (rte_kvargs_to_uint(args.memory_ranks, 1, 16, &ranks) < 0) {
 			EAL_LOG(ERR, "invalid memory rank parameter");
 			return -1;
 		}
+		int_cfg->force_nrank = ranks;
 	}
 	if (args.no_huge) {
 		int_cfg->no_hugetlbfs = 1;
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help