The driver was not correctly validating the arguments for packet_size,
packet_copy, and no_rx. The original parsing had several issues:
- Empty strings were not rejected
- Trailing non-numeric characters were silently ignored
- Large values could wrap around causing unexpected behavior
Add a common helper function get_unsigned_arg() that properly validates
numeric arguments by checking for empty input, ensuring the entire
string is consumed, and enforcing appropriate maximum values for each
parameter.
Fixes: 4df90194f2a2 ("net/null: prefer unsigned int")
Cc: [email protected]
Signed-off-by: Stephen Hemminger <[email protected]>
---
drivers/net/null/rte_eth_null.c | 59 +++++++++++++++------------------
1 file changed, 26 insertions(+), 33 deletions(-)
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index ba87c82a73..cd7a29bce9 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -602,56 +602,49 @@ eth_dev_null_create(struct rte_vdev_device *dev, struct
pmd_options *args)
return 0;
}
-static inline int
-get_packet_size_arg(const char *key __rte_unused,
- const char *value, void *extra_args)
+static int
+get_unsigned_arg(const char *str, unsigned int *retval,
+ unsigned int maxval)
{
- const char *a = value;
- unsigned int *packet_size = extra_args;
+ char *endp = NULL;
+ unsigned long val;
- if ((value == NULL) || (extra_args == NULL))
+ if (str == NULL || retval == NULL)
return -EINVAL;
- *packet_size = (unsigned int)strtoul(a, NULL, 0);
- if (*packet_size == UINT_MAX)
- return -1;
+ if (*str == '\0')
+ return -EINVAL; /* empty string */
+ val = strtoul(str, &endp, 0);
+ if (*endp != '\0')
+ return -EINVAL; /* non-numeric character */
+
+ if (val > maxval)
+ return -ERANGE;
+
+ *retval = val;
return 0;
}
-static inline int
-get_packet_copy_arg(const char *key __rte_unused,
+static int
+get_packet_size_arg(const char *key __rte_unused,
const char *value, void *extra_args)
{
- const char *a = value;
- unsigned int *packet_copy = extra_args;
-
- if ((value == NULL) || (extra_args == NULL))
- return -EINVAL;
-
- *packet_copy = (unsigned int)strtoul(a, NULL, 0);
- if (*packet_copy == UINT_MAX)
- return -1;
+ return get_unsigned_arg(value, extra_args, UINT16_MAX);
+}
- return 0;
+static int
+get_packet_copy_arg(const char *key __rte_unused,
+ const char *value, void *extra_args)
+{
+ return get_unsigned_arg(value, extra_args, UINT32_MAX);
}
static int
get_packet_no_rx_arg(const char *key __rte_unused,
const char *value, void *extra_args)
{
- const char *a = value;
- unsigned int no_rx;
-
- if (value == NULL || extra_args == NULL)
- return -EINVAL;
-
- no_rx = (unsigned int)strtoul(a, NULL, 0);
- if (no_rx != 0 && no_rx != 1)
- return -1;
-
- *(unsigned int *)extra_args = no_rx;
- return 0;
+ return get_unsigned_arg(value, extra_args, 1);
}
static int
--
2.51.0