public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2] lib: add input validation for time, rate, and size parsing functions
@ 2026-04-21 20:23 Stephen Hemminger
  0 siblings, 0 replies; only message in thread
From: Stephen Hemminger @ 2026-04-21 20:23 UTC (permalink / raw)
  To: netdev; +Cc: Stephen Hemminger

The parsing functions get_time(), get_time64(), get_rate(), get_rate64(),
and get_size64() use strtod() to convert user input but don't validate
the parsed values. This allows negative numbers and overflow values to
be passed through, which can cause unexpected behavior or security issues
when these values reach the kernel as unsigned integers.

Add validation to reject:
- Negative values (which make no sense for time, rate, or size)
- Overflow conditions (when strtod() returns HUGE_VAL with ERANGE)
- Empty strings (already checked, but now with explicit comments)

This prevents potential issues and provides clearer error reporting.
Fixing it in iproute2 does not mean that the kernel is off the hook
for handling negative values. Checks are still needed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/utils.c      | 16 ++++++++++++++--
 lib/utils_math.c | 25 ++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/lib/utils.c b/lib/utils.c
index 1215fe31..50602e59 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1647,7 +1647,13 @@ int get_time(unsigned int *time, const char *str)
 
 	t = strtod(str, &p);
 	if (p == str)
-		return -1;
+		return -1;	/* empty string */
+
+	if (t < 0)
+		return -1;	/* negative value */
+
+	if (t == HUGE_VAL && errno == ERANGE)
+		return -1;	/* out of range */
 
 	if (*p) {
 		if (strcasecmp(p, "s") == 0 || strcasecmp(p, "sec") == 0 ||
@@ -1693,7 +1699,13 @@ int get_time64(__s64 *time, const char *str)
 
 	nsec = strtod(str, &p);
 	if (p == str)
-		return -1;
+		return -1;	/* empty string */
+
+	if (nsec < 0)
+		return -1;	/* negative value */
+
+	if (nsec == HUGE_VAL && errno == ERANGE)
+		return -1;	/* out of range */
 
 	if (*p) {
 		if (strcasecmp(p, "s") == 0 ||
diff --git a/lib/utils_math.c b/lib/utils_math.c
index fd2ddc7c..4b0ac266 100644
--- a/lib/utils_math.c
+++ b/lib/utils_math.c
@@ -5,6 +5,7 @@
 #include <string.h>
 #include <math.h>
 #include <limits.h>
+#include <errno.h>
 #include <asm/types.h>
 
 #include "utils.h"
@@ -42,7 +43,13 @@ int get_rate(unsigned int *rate, const char *str)
 	const struct rate_suffix *s;
 
 	if (p == str)
-		return -1;
+		return -1;	/* empty string */
+
+	if (bps < 0)
+		return -1;	/* negative */
+
+	if (bps == HUGE_VAL && errno == ERANGE)
+		return -1;	/* out of range */
 
 	for (s = suffixes; s->name; ++s) {
 		if (strcasecmp(s->name, p) == 0) {
@@ -70,7 +77,13 @@ int get_rate64(__u64 *rate, const char *str)
 	const struct rate_suffix *s;
 
 	if (p == str)
-		return -1;
+		return -1;	/* empty string */
+
+	if (bps < 0)
+		return -1;	/* negative */
+
+	if (bps == HUGE_VAL && errno == ERANGE)
+		return -1;	/* out of range */
 
 	for (s = suffixes; s->name; ++s) {
 		if (strcasecmp(s->name, p) == 0) {
@@ -95,7 +108,13 @@ int get_size64(__u64 *size, const char *str)
 
 	sz = strtod(str, &p);
 	if (p == str)
-		return -1;
+		return -1;	/* empty string */
+
+	if (sz < 0)
+		return -1;	/* negative */
+
+	if (sz == HUGE_VAL && errno == ERANGE)
+		return -1;	/* out of range */
 
 	if (*p) {
 		if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k") == 0)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-04-21 20:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-21 20:23 [PATCH iproute2] lib: add input validation for time, rate, and size parsing functions Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox