* [PATCH] net/af_packet: fix qpairs argument upper bound check
@ 2026-06-03 4:42 Denis Sergeev
2026-06-03 15:27 ` Stephen Hemminger
2026-06-03 17:08 ` [PATCH v2] " Denis Sergeev
0 siblings, 2 replies; 4+ messages in thread
From: Denis Sergeev @ 2026-06-03 4:42 UTC (permalink / raw)
To: dev; +Cc: stephen, sdl.dpdk, Denis Sergeev
The qpairs vdev argument parsed via atoi() is stored in an
unsigned int. A negative input such as "-1" wraps to UINT_MAX,
passes the existing "< 1" check, and reaches
rte_pmd_init_internals() as nb_queues. This causes excessive
socket and memory allocation in the per-queue loop.
Add an upper bound check against RTE_MAX_QUEUES_PER_PORT.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: ccd37d341e8d ("net/af_packet: remove queue number limitation")
Signed-off-by: Denis Sergeev <denserg.edu@gmail.com>
---
drivers/net/af_packet/rte_eth_af_packet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 0ee94e71ea..ebf015dd9a 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -1169,7 +1169,7 @@ rte_eth_from_packet(struct rte_vdev_device *dev,
pair = &kvlist->pairs[k_idx];
if (strstr(pair->key, ETH_AF_PACKET_NUM_Q_ARG) != NULL) {
qpairs = atoi(pair->value);
- if (qpairs < 1) {
+ if (qpairs < 1 || qpairs > RTE_MAX_QUEUES_PER_PORT) {
PMD_LOG(ERR,
"%s: invalid qpairs value",
name);
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] net/af_packet: fix qpairs argument upper bound check 2026-06-03 4:42 [PATCH] net/af_packet: fix qpairs argument upper bound check Denis Sergeev @ 2026-06-03 15:27 ` Stephen Hemminger 2026-06-03 17:08 ` [PATCH v2] " Denis Sergeev 1 sibling, 0 replies; 4+ messages in thread From: Stephen Hemminger @ 2026-06-03 15:27 UTC (permalink / raw) To: Denis Sergeev; +Cc: dev, sdl.dpdk On Wed, 3 Jun 2026 07:42:18 +0300 Denis Sergeev <denserg.edu@gmail.com> wrote: > diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c > index 0ee94e71ea..ebf015dd9a 100644 > --- a/drivers/net/af_packet/rte_eth_af_packet.c > +++ b/drivers/net/af_packet/rte_eth_af_packet.c > @@ -1169,7 +1169,7 @@ rte_eth_from_packet(struct rte_vdev_device *dev, > pair = &kvlist->pairs[k_idx]; > if (strstr(pair->key, ETH_AF_PACKET_NUM_Q_ARG) != NULL) { > qpairs = atoi(pair->value); > - if (qpairs < 1) { > + if (qpairs < 1 || qpairs > RTE_MAX_QUEUES_PER_PORT) { > PMD_LOG(ERR, > "%s: invalid qpairs value", > name); > -- I would rather see atoi() not used in DPDK, it accepts too much and does not do enough validation. Replace with strtoul() instead. ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2] net/af_packet: fix qpairs argument upper bound check 2026-06-03 4:42 [PATCH] net/af_packet: fix qpairs argument upper bound check Denis Sergeev 2026-06-03 15:27 ` Stephen Hemminger @ 2026-06-03 17:08 ` Denis Sergeev 2026-06-03 18:13 ` [PATCH] net/af_packet: fix parsing of numeric device args Stephen Hemminger 1 sibling, 1 reply; 4+ messages in thread From: Denis Sergeev @ 2026-06-03 17:08 UTC (permalink / raw) To: dev; +Cc: stephen, Denis Sergeev The qpairs vdev argument was parsed with atoi(), which does no validation: trailing garbage is ignored and a negative input such as "-1" wraps to UINT_MAX when stored in the unsigned qpairs field, passing the existing "< 1" check and reaching rte_pmd_init_internals() as nb_queues. This causes excessive socket and memory allocation in the per-queue loop. Parse the value with strtoul() and reject non-numeric input, trailing characters, negative values and values outside the [1, RTE_MAX_QUEUES_PER_PORT] range. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: ccd37d341e8d ("net/af_packet: remove queue number limitation") Signed-off-by: Denis Sergeev <denserg.edu@gmail.com> --- v2: * Replace atoi() with strtoul() and validate the parsed value drivers/net/af_packet/rte_eth_af_packet.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index 8303ff5ca9..b7758a5c75 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -1168,13 +1168,20 @@ rte_eth_from_packet(struct rte_vdev_device *dev, for (k_idx = 0; k_idx < kvlist->count; k_idx++) { pair = &kvlist->pairs[k_idx]; if (strstr(pair->key, ETH_AF_PACKET_NUM_Q_ARG) != NULL) { - qpairs = atoi(pair->value); - if (qpairs < 1) { + char *endptr; + unsigned long num; + + errno = 0; + num = strtoul(pair->value, &endptr, 10); + if (errno != 0 || endptr == pair->value || + *endptr != '\0' || pair->value[0] == '-' || + num < 1 || num > RTE_MAX_QUEUES_PER_PORT) { PMD_LOG(ERR, "%s: invalid qpairs value", name); return -1; } + qpairs = num; continue; } if (strstr(pair->key, ETH_AF_PACKET_BLOCKSIZE_ARG) != NULL) { -- 2.50.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH] net/af_packet: fix parsing of numeric device args 2026-06-03 17:08 ` [PATCH v2] " Denis Sergeev @ 2026-06-03 18:13 ` Stephen Hemminger 0 siblings, 0 replies; 4+ messages in thread From: Stephen Hemminger @ 2026-06-03 18:13 UTC (permalink / raw) To: dev; +Cc: Stephen Hemminger, Denis Sergeev, stable, John W. Linville This driver has several numeric arguments but it was using atoi() which allows garbage and negative values. Convert to a helper using strtoul() with upper bound. First found by Linux Verification Center (linuxtesting.org) with SVACE. Reported-by: Denis Sergeev <denserg.edu@gmail.com> Fixes: 364e08f2bbc0 ("af_packet: add PMD for AF_PACKET-based virtual devices") Cc: stable@dpdk.org Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> --- drivers/net/af_packet/rte_eth_af_packet.c | 58 +++++++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index 8303ff5ca9..b0ff22ea55 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -15,7 +15,9 @@ #include <rte_kvargs.h> #include <bus_vdev_driver.h> +#include <ctype.h> #include <errno.h> +#include <limits.h> #include <linux/if_ether.h> #include <linux/if_packet.h> #include <arpa/inet.h> @@ -1138,6 +1140,42 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, return -1; } +/* Parse an unsigned integer device argument. */ +static int +parse_uint(const char *key, const char *value, + unsigned int *out, unsigned long limit) +{ + unsigned long val; + char *endptr; + + if (value == NULL) { + PMD_LOG(ERR, "no value for argument \"%s\"", key); + return -1; + } + + /* Skip leading whitespace so a leading sign can be detected. */ + while (isspace((unsigned char)*value)) + value++; + + /* strtoul() silently accepts and negates a leading '-'. */ + if (*value == '\0' || *value == '-') { + PMD_LOG(ERR, "invalid value \"%s\" for argument \"%s\"", + value, key); + return -1; + } + + errno = 0; + val = strtoul(value, &endptr, 10); + if (errno != 0 || *endptr != '\0' || val > limit) { + PMD_LOG(ERR, "invalid value \"%s\" for argument \"%s\"", + value, key); + return -1; + } + + *out = (unsigned int)val; + return 0; +} + static int rte_eth_from_packet(struct rte_vdev_device *dev, int const *sockfd, @@ -1168,7 +1206,9 @@ rte_eth_from_packet(struct rte_vdev_device *dev, for (k_idx = 0; k_idx < kvlist->count; k_idx++) { pair = &kvlist->pairs[k_idx]; if (strstr(pair->key, ETH_AF_PACKET_NUM_Q_ARG) != NULL) { - qpairs = atoi(pair->value); + if (parse_uint(pair->key, pair->value, + &qpairs, RTE_MAX_QUEUES_PER_PORT) < 0) + return -1; if (qpairs < 1) { PMD_LOG(ERR, "%s: invalid qpairs value", @@ -1178,7 +1218,8 @@ rte_eth_from_packet(struct rte_vdev_device *dev, continue; } if (strstr(pair->key, ETH_AF_PACKET_BLOCKSIZE_ARG) != NULL) { - blocksize = atoi(pair->value); + if (parse_uint(pair->key, pair->value, &blocksize, UINT_MAX) < 0) + return -1; if (!blocksize) { PMD_LOG(ERR, "%s: invalid blocksize value", @@ -1188,7 +1229,8 @@ rte_eth_from_packet(struct rte_vdev_device *dev, continue; } if (strstr(pair->key, ETH_AF_PACKET_FRAMESIZE_ARG) != NULL) { - framesize = atoi(pair->value); + if (parse_uint(pair->key, pair->value, &framesize, UINT_MAX) < 0) + return -1; if (!framesize) { PMD_LOG(ERR, "%s: invalid framesize value", @@ -1198,7 +1240,8 @@ rte_eth_from_packet(struct rte_vdev_device *dev, continue; } if (strstr(pair->key, ETH_AF_PACKET_FRAMECOUNT_ARG) != NULL) { - framecount = atoi(pair->value); + if (parse_uint(pair->key, pair->value, &framecount, UINT_MAX) < 0) + return -1; if (!framecount) { PMD_LOG(ERR, "%s: invalid framecount value", @@ -1208,13 +1251,8 @@ rte_eth_from_packet(struct rte_vdev_device *dev, continue; } if (strstr(pair->key, ETH_AF_PACKET_QDISC_BYPASS_ARG) != NULL) { - qdisc_bypass = atoi(pair->value); - if (qdisc_bypass > 1) { - PMD_LOG(ERR, - "%s: invalid bypass value", - name); + if (parse_uint(pair->key, pair->value, &qdisc_bypass, 1) < 0) return -1; - } continue; } if (strstr(pair->key, ETH_AF_PACKET_FANOUT_MODE_ARG) != NULL) { -- 2.53.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-03 18:13 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-03 4:42 [PATCH] net/af_packet: fix qpairs argument upper bound check Denis Sergeev 2026-06-03 15:27 ` Stephen Hemminger 2026-06-03 17:08 ` [PATCH v2] " Denis Sergeev 2026-06-03 18:13 ` [PATCH] net/af_packet: fix parsing of numeric device args Stephen Hemminger
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox