From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
Yipeng Wang <yipeng1.wang@intel.com>,
Sameh Gobriel <sameh.gobriel@intel.com>,
Bruce Richardson <bruce.richardson@intel.com>,
Vladimir Medvedkin <vladimir.medvedkin@intel.com>
Subject: [PATCH v3 03/16] hash: add checks for hash name length
Date: Fri, 5 Dec 2025 12:11:32 -0800 [thread overview]
Message-ID: <20251205201537.251131-4-stephen@networkplumber.org> (raw)
In-Reply-To: <20251205201537.251131-1-stephen@networkplumber.org>
Add a missing check to the API that the name is within the current
defined maximum name size. This name is then used internally to
create ring names, those names could get truncated; if a name
is truncated add message to log.
If ring creation fails it might be because of name conflict,
so change the log message to decode error value.
Add additional tests as well.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_hash.c | 21 +++++++++++++
doc/guides/rel_notes/release_26_03.rst | 3 ++
lib/hash/rte_cuckoo_hash.c | 41 ++++++++++++++++++--------
lib/hash/rte_fbk_hash.c | 13 ++++++--
4 files changed, 64 insertions(+), 14 deletions(-)
diff --git a/app/test/test_hash.c b/app/test/test_hash.c
index 5791fd7f4c..0b608a3d74 100644
--- a/app/test/test_hash.c
+++ b/app/test/test_hash.c
@@ -1120,6 +1120,14 @@ fbk_hash_unit_test(void)
.socket_id = RTE_MAX_NUMA_NODES + 1, /* invalid socket */
};
+ /* try and create hash with an excessively long name */
+ struct rte_fbk_hash_params invalid_params_long_name = {
+ .name = "four_byte_key_hash_name_length_32",
+ .entries = 4,
+ .entries_per_bucket = 2,
+ .socket_id = 0,
+ };
+
/* try to create two hashes with identical names
* in this case, trying to create a second one will not
* fail but will simply return pointer to the existing
@@ -1201,6 +1209,9 @@ fbk_hash_unit_test(void)
handle = rte_fbk_hash_create(&invalid_params_7);
RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed");
+ handle = rte_fbk_hash_create(&invalid_params_long_name);
+ RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed");
+
if (rte_eal_has_hugepages()) {
handle = rte_fbk_hash_create(&invalid_params_8);
RETURN_IF_ERROR_FBK(handle != NULL,
@@ -1439,6 +1450,16 @@ static int test_hash_creation_with_bad_parameters(void)
return -1;
}
+ memcpy(¶ms, &ut_params, sizeof(params));
+ params.name = "hash_creation_with_too_long_name";
+ params.socket_id = RTE_MAX_NUMA_NODES + 1;
+ handle = rte_hash_create(¶ms);
+ if (handle != NULL) {
+ rte_hash_free(handle);
+ printf("Impossible creating hash successfully with long name\n");
+ return -1;
+ }
+
/* test with same name should fail */
memcpy(¶ms, &ut_params, sizeof(params));
params.name = "same_name";
diff --git a/doc/guides/rel_notes/release_26_03.rst b/doc/guides/rel_notes/release_26_03.rst
index 15dabee7a1..a12bd41e86 100644
--- a/doc/guides/rel_notes/release_26_03.rst
+++ b/doc/guides/rel_notes/release_26_03.rst
@@ -84,6 +84,9 @@ API Changes
Also, make sure to start the actual text at the margin.
=======================================================
+* hash: Added name length validation to hash creation.
+ The hash name in hash parameters is now checked against RTE_HASH_NAMESIZE.
+
ABI Changes
-----------
diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c
index 2c92c51624..f9c4a0e302 100644
--- a/lib/hash/rte_cuckoo_hash.c
+++ b/lib/hash/rte_cuckoo_hash.c
@@ -170,7 +170,6 @@ rte_hash_create(const struct rte_hash_parameters *params)
void *buckets = NULL;
void *buckets_ext = NULL;
char ring_name[RTE_RING_NAMESIZE];
- char ext_ring_name[RTE_RING_NAMESIZE];
unsigned num_key_slots;
unsigned int hw_trans_mem_support = 0, use_local_cache = 0;
unsigned int ext_table_support = 0;
@@ -222,6 +221,13 @@ rte_hash_create(const struct rte_hash_parameters *params)
return NULL;
}
+ if (strlen(params->name) >= RTE_HASH_NAMESIZE) {
+ rte_errno = ENAMETOOLONG;
+ HASH_LOG(ERR, "%s() name '%s' exceeds maximum length %d",
+ __func__, params->name, RTE_HASH_NAMESIZE);
+ return NULL;
+ }
+
/* Validate correct usage of extra options */
if ((params->extra_flag & RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY) &&
(params->extra_flag & RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF)) {
@@ -272,12 +278,16 @@ rte_hash_create(const struct rte_hash_parameters *params)
else
num_key_slots = params->entries + 1;
- snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name);
+ /* Ring name may get truncated, conflict detected on ring creation */
+ if (snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name)
+ >= (int)sizeof(ring_name))
+ HASH_LOG(NOTICE, "ring name truncated to '%s'", ring_name);
+
/* Create ring (Dummy slot index is not enqueued) */
r = rte_ring_create_elem(ring_name, sizeof(uint32_t),
rte_align32pow2(num_key_slots), params->socket_id, 0);
if (r == NULL) {
- HASH_LOG(ERR, "memory allocation failed");
+ HASH_LOG(ERR, "ring creation failed: %s", rte_strerror(rte_errno));
goto err;
}
@@ -286,20 +296,25 @@ rte_hash_create(const struct rte_hash_parameters *params)
/* Create ring for extendable buckets. */
if (ext_table_support) {
- snprintf(ext_ring_name, sizeof(ext_ring_name), "HT_EXT_%s",
- params->name);
+ char ext_ring_name[RTE_RING_NAMESIZE];
+
+ if (snprintf(ext_ring_name, sizeof(ext_ring_name),
+ "HT_EXT_%s", params->name) >= (int)sizeof(ext_ring_name))
+ HASH_LOG(NOTICE, "external ring name truncated to '%s'", ext_ring_name);
+
r_ext = rte_ring_create_elem(ext_ring_name, sizeof(uint32_t),
rte_align32pow2(num_buckets + 1),
params->socket_id, 0);
-
if (r_ext == NULL) {
- HASH_LOG(ERR, "ext buckets memory allocation "
- "failed");
+ HASH_LOG(ERR, "ext buckets ring create failed: %s",
+ rte_strerror(rte_errno));
goto err;
}
}
- snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name);
+ if (snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name)
+ >= (int)sizeof(hash_name))
+ HASH_LOG(NOTICE, "%s() hash name truncated to '%s'", __func__, hash_name);
rte_mcfg_tailq_write_lock();
@@ -1606,8 +1621,9 @@ rte_hash_rcu_qsbr_add(struct rte_hash *h, struct rte_hash_rcu_config *cfg)
/* No other things to do. */
} else if (cfg->mode == RTE_HASH_QSBR_MODE_DQ) {
/* Init QSBR defer queue. */
- snprintf(rcu_dq_name, sizeof(rcu_dq_name),
- "HASH_RCU_%s", h->name);
+ if (snprintf(rcu_dq_name, sizeof(rcu_dq_name),
+ "HASH_RCU_%s", h->name) >= (int)sizeof(rcu_dq_name))
+ HASH_LOG(NOTICE, "HASH defer queue name truncated to: %s", rcu_dq_name);
params.name = rcu_dq_name;
params.size = cfg->dq_size;
if (params.size == 0)
@@ -1623,7 +1639,8 @@ rte_hash_rcu_qsbr_add(struct rte_hash *h, struct rte_hash_rcu_config *cfg)
h->dq = rte_rcu_qsbr_dq_create(¶ms);
if (h->dq == NULL) {
rte_free(hash_rcu_cfg);
- HASH_LOG(ERR, "HASH defer queue creation failed");
+ HASH_LOG(ERR, "HASH defer queue creation failed: %s",
+ rte_strerror(rte_errno));
return 1;
}
} else {
diff --git a/lib/hash/rte_fbk_hash.c b/lib/hash/rte_fbk_hash.c
index 38b15a14d1..f60fad3caa 100644
--- a/lib/hash/rte_fbk_hash.c
+++ b/lib/hash/rte_fbk_hash.c
@@ -83,7 +83,7 @@ rte_fbk_hash_create(const struct rte_fbk_hash_params *params)
{
struct rte_fbk_hash_table *ht = NULL;
struct rte_tailq_entry *te;
- char hash_name[RTE_FBK_HASH_NAMESIZE];
+ char *hash_name = NULL;
const uint32_t mem_size =
sizeof(*ht) + (sizeof(ht->t[0]) * params->entries);
uint32_t i;
@@ -96,6 +96,7 @@ rte_fbk_hash_create(const struct rte_fbk_hash_params *params)
/* Error checking of parameters. */
if ((!rte_is_power_of_2(params->entries)) ||
(!rte_is_power_of_2(params->entries_per_bucket)) ||
+ (params->name == NULL) ||
(params->entries == 0) ||
(params->entries_per_bucket == 0) ||
(params->entries_per_bucket > params->entries) ||
@@ -105,7 +106,14 @@ rte_fbk_hash_create(const struct rte_fbk_hash_params *params)
return NULL;
}
- snprintf(hash_name, sizeof(hash_name), "FBK_%s", params->name);
+ if (strlen(params->name) >= RTE_FBK_HASH_NAMESIZE) {
+ rte_errno = ENAMETOOLONG;
+ return NULL;
+ }
+
+ /* don't care if hash_name is NULL */
+ int unused __rte_unused;
+ unused = asprintf(&hash_name, "FBK_%s", params->name);
rte_mcfg_tailq_write_lock();
@@ -170,6 +178,7 @@ rte_fbk_hash_create(const struct rte_fbk_hash_params *params)
exit:
rte_mcfg_tailq_write_unlock();
+ free(hash_name);
return ht;
}
--
2.51.0
next prev parent reply other threads:[~2025-12-05 20:16 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-02 17:24 [RFC 0/8] first steps in fixing buffer overflow Stephen Hemminger
2025-12-02 17:24 ` [RFC 1/8] eal: use C library to parse filesystem table Stephen Hemminger
2025-12-02 17:24 ` [RFC 2/8] hash: fix possible ring name overflow Stephen Hemminger
2025-12-02 17:24 ` [RFC 3/8] eal: warn if thread name is truncated Stephen Hemminger
2025-12-02 17:24 ` [RFC 4/8] eal: avoid format overflow when handling addresses Stephen Hemminger
2025-12-02 17:24 ` [RFC 5/8] ethdev: avoid possible overflow in xstat names Stephen Hemminger
2025-12-02 17:24 ` [RFC 6/8] efd: avoid overflowing ring name Stephen Hemminger
2025-12-02 17:24 ` [RFC 7/8] eal: add check for sysfs path overflow Stephen Hemminger
2025-12-02 17:24 ` [RFC 8/8] eal: limit maximum runtime directory and socket paths Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 00/14] lib: check for string overflow Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 01/14] eal: use C library to parse filesystem table Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 02/14] test: avoid long hash names Stephen Hemminger
2025-12-05 8:29 ` Bruce Richardson
2025-12-05 17:00 ` Stephen Hemminger
2025-12-05 18:19 ` Bruce Richardson
2025-12-05 2:28 ` [RFC v2 03/14] lpm: restrict name size Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 04/14] hash: avoid possible ring name overflow Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 05/14] graph: avoid overflowing comment buffer Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 06/14] eal: warn if thread name is truncated Stephen Hemminger
2025-12-05 8:32 ` Bruce Richardson
2025-12-05 2:28 ` [RFC v2 07/14] eal: avoid format overflow when handling addresses Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 08/14] ethdev: avoid possible overflow in xstat names Stephen Hemminger
2025-12-05 8:34 ` Bruce Richardson
2025-12-05 2:28 ` [RFC v2 09/14] vhost: check for overflow in xstat name Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 10/14] efd: avoid overflowing ring name Stephen Hemminger
2025-12-05 8:37 ` Bruce Richardson
2025-12-05 2:28 ` [RFC v2 11/14] eal: add check for sysfs path overflow Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 12/14] eal: limit maximum runtime directory and socket paths Stephen Hemminger
2025-12-05 8:46 ` Bruce Richardson
2025-12-05 2:28 ` [RFC v2 13/14] eal: check for hugefile path overflow Stephen Hemminger
2025-12-05 2:28 ` [RFC v2 14/14] lib: enable format overflow warnings Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 00/16] lib: find and fix possible string overflows Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 01/16] eal: use C library to parse filesystem table Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 02/16] lpm: restrict name size Stephen Hemminger
2025-12-05 20:11 ` Stephen Hemminger [this message]
2025-12-05 20:11 ` [PATCH v3 04/16] graph: avoid overflowing comment buffer Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 05/16] latencystats: add check for string overflow Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 06/16] efd: handle possible name truncation Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 07/16] eal: warn if thread name is truncated Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 08/16] eal: avoid format overflow when handling addresses Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 09/16] eal: add check for sysfs path overflow Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 10/16] eal: limit maximum runtime directory and socket paths Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 11/16] eal: check for hugefile path overflow Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 12/16] eal: check tailq length Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 13/16] eal: handle long shared library path Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 14/16] ethdev: avoid possible overflow in xstat names Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 15/16] vhost: check for overflow in xstat name Stephen Hemminger
2025-12-05 20:11 ` [PATCH v3 16/16] lib: enable format overflow warnings Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251205201537.251131-4-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=sameh.gobriel@intel.com \
--cc=vladimir.medvedkin@intel.com \
--cc=yipeng1.wang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).