patch 'hash: fix overflow of 32-bit offsets' has been queued to stable release 24.11.5

luca.boccassi at gmail.com luca.boccassi at gmail.com
Thu Mar 19 23:01:59 CET 2026


Hi,

FYI, your patch has been queued to stable release 24.11.5

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 03/21/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable

This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/8dad78c4619b5abdab14d5be9ad15f4810744fdf

Thanks.

Luca Boccassi

---
>From 8dad78c4619b5abdab14d5be9ad15f4810744fdf Mon Sep 17 00:00:00 2001
From: Bruce Richardson <bruce.richardson at intel.com>
Date: Fri, 27 Feb 2026 13:01:27 +0000
Subject: [PATCH] hash: fix overflow of 32-bit offsets
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

[ upstream commit 476a0536b004984e47bd49e36e99949a8b95c701 ]

When computing the offset inside the overall hash structure by adding an
offset to a base pointer, the offset was generally calculated by
multiplying two 32-bit values, which could then overflow. Prevent
overflow by using (size_t) casts on the elements being multiplied to
ensure they are 64-bit on 64-bit systems.

Fixes: b26473ff8f4a ("hash: add reset function")
Fixes: 406da3dfb3b5 ("hash: move duplicated code into functions")
Fixes: 9eca8bd7a61c ("hash: separate lock-free and r/w lock lookup")
Fixes: 4d9ca3ed2133 ("hash: use ordered loads only if signature matches")
Fixes: 769b2de7fb52 ("hash: implement RCU resources reclamation")
Fixes: e605a1d36ca7 ("hash: add lock-free r/w concurrency")
Fixes: 6dc34e0afe7a ("hash: retrieve a key given its position")
Fixes: f9edbc9bb6bc ("hash: add iterate function")
Fixes: 75706568a7eb ("hash: add extendable bucket feature")

Signed-off-by: Bruce Richardson <bruce.richardson at intel.com>
Acked-by: Morten Brørup <mb at smartsharesystems.com>
---
 lib/hash/rte_cuckoo_hash.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c
index 9575e8aa0c..03bf2ab356 100644
--- a/lib/hash/rte_cuckoo_hash.c
+++ b/lib/hash/rte_cuckoo_hash.c
@@ -681,7 +681,7 @@ rte_hash_reset(struct rte_hash *h)
 	}
 
 	memset(h->buckets, 0, h->num_buckets * sizeof(struct rte_hash_bucket));
-	memset(h->key_store, 0, h->key_entry_size * (h->entries + 1));
+	memset(h->key_store, 0, (size_t)h->key_entry_size * (h->entries + 1));
 	*h->tbl_chng_cnt = 0;
 
 	/* reset the free ring */
@@ -750,7 +750,7 @@ search_and_update(const struct rte_hash *h, void *data, const void *key,
 	for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
 		if (bkt->sig_current[i] == sig) {
 			k = (struct rte_hash_key *) ((char *)keys +
-					bkt->key_idx[i] * h->key_entry_size);
+					bkt->key_idx[i] * (size_t)h->key_entry_size);
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
 				/* The store to application data at *data
 				 * should not leak after the store to pdata
@@ -1116,7 +1116,7 @@ __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
 			return -ENOSPC;
 	}
 
-	new_k = RTE_PTR_ADD(keys, slot_id * h->key_entry_size);
+	new_k = RTE_PTR_ADD(keys, slot_id * (size_t)h->key_entry_size);
 	/* The store to application data (by the application) at *data should
 	 * not leak after the store of pdata in the key store. i.e. pdata is
 	 * the guard variable. Release the application data to the readers.
@@ -1301,7 +1301,7 @@ search_one_bucket_l(const struct rte_hash *h, const void *key,
 		if (bkt->sig_current[i] == sig &&
 				bkt->key_idx[i] != EMPTY_SLOT) {
 			k = (struct rte_hash_key *) ((char *)keys +
-					bkt->key_idx[i] * h->key_entry_size);
+					bkt->key_idx[i] * (size_t)h->key_entry_size);
 
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
 				if (data != NULL)
@@ -1339,7 +1339,7 @@ search_one_bucket_lf(const struct rte_hash *h, const void *key, uint16_t sig,
 					  rte_memory_order_acquire);
 			if (key_idx != EMPTY_SLOT) {
 				k = (struct rte_hash_key *) ((char *)keys +
-						key_idx * h->key_entry_size);
+						key_idx * (size_t)h->key_entry_size);
 
 				if (rte_hash_cmp_eq(key, k->key, h) == 0) {
 					if (data != NULL) {
@@ -1537,7 +1537,7 @@ __hash_rcu_qsbr_free_resource(void *p, void *e, unsigned int n)
 	keys = h->key_store;
 
 	k = (struct rte_hash_key *) ((char *)keys +
-				rcu_dq_entry.key_idx * h->key_entry_size);
+				rcu_dq_entry.key_idx * (size_t)h->key_entry_size);
 	key_data = k->pdata;
 	if (h->hash_rcu_cfg->free_key_data_func)
 		h->hash_rcu_cfg->free_key_data_func(h->hash_rcu_cfg->key_data_ptr,
@@ -1721,7 +1721,7 @@ search_and_remove(const struct rte_hash *h, const void *key,
 					  rte_memory_order_acquire);
 		if (bkt->sig_current[i] == sig && key_idx != EMPTY_SLOT) {
 			k = (struct rte_hash_key *) ((char *)keys +
-					key_idx * h->key_entry_size);
+					key_idx * (size_t)h->key_entry_size);
 			if (rte_hash_cmp_eq(key, k->key, h) == 0) {
 				bkt->sig_current[i] = NULL_SIGNATURE;
 				/* Free the key store index if
@@ -1873,8 +1873,7 @@ rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
 	RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
 
 	struct rte_hash_key *k, *keys = h->key_store;
-	k = (struct rte_hash_key *) ((char *) keys + (position + 1) *
-				     h->key_entry_size);
+	k = (struct rte_hash_key *) ((char *) keys + (position + 1) * (size_t)h->key_entry_size);
 	*key = k->key;
 
 	if (position !=
@@ -1967,7 +1966,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
 			const struct rte_hash_key *key_slot =
 				(const struct rte_hash_key *)(
 				(const char *)h->key_store +
-				key_idx * h->key_entry_size);
+				key_idx * (size_t)h->key_entry_size);
 			rte_prefetch0(key_slot);
 			continue;
 		}
@@ -1981,7 +1980,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
 			const struct rte_hash_key *key_slot =
 				(const struct rte_hash_key *)(
 				(const char *)h->key_store +
-				key_idx * h->key_entry_size);
+				key_idx * (size_t)h->key_entry_size);
 			rte_prefetch0(key_slot);
 		}
 	}
@@ -2006,7 +2005,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
 			const struct rte_hash_key *key_slot =
 				(const struct rte_hash_key *)(
 				(const char *)h->key_store +
-				key_idx * h->key_entry_size);
+				key_idx * (size_t)h->key_entry_size);
 
 			/*
 			 * If key index is 0, do not compare key,
@@ -2034,7 +2033,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
 			const struct rte_hash_key *key_slot =
 				(const struct rte_hash_key *)(
 				(const char *)h->key_store +
-				key_idx * h->key_entry_size);
+				key_idx * (size_t)h->key_entry_size);
 
 			/*
 			 * If key index is 0, do not compare key,
@@ -2153,7 +2152,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
 				const struct rte_hash_key *key_slot =
 					(const struct rte_hash_key *)(
 					(const char *)h->key_store +
-					key_idx * h->key_entry_size);
+					key_idx * (size_t)h->key_entry_size);
 				rte_prefetch0(key_slot);
 				continue;
 			}
@@ -2167,7 +2166,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
 				const struct rte_hash_key *key_slot =
 					(const struct rte_hash_key *)(
 					(const char *)h->key_store +
-					key_idx * h->key_entry_size);
+					key_idx * (size_t)h->key_entry_size);
 				rte_prefetch0(key_slot);
 			}
 		}
@@ -2193,7 +2192,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
 				const struct rte_hash_key *key_slot =
 					(const struct rte_hash_key *)(
 					(const char *)h->key_store +
-					key_idx * h->key_entry_size);
+					key_idx * (size_t)h->key_entry_size);
 
 				/*
 				 * If key index is 0, do not compare key,
@@ -2225,7 +2224,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
 				const struct rte_hash_key *key_slot =
 					(const struct rte_hash_key *)(
 					(const char *)h->key_store +
-					key_idx * h->key_entry_size);
+					key_idx * (size_t)h->key_entry_size);
 
 				/*
 				 * If key index is 0, do not compare key,
@@ -2576,7 +2575,7 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32
 
 	__hash_rw_reader_lock(h);
 	next_key = (struct rte_hash_key *) ((char *)h->key_store +
-				position * h->key_entry_size);
+				position * (size_t)h->key_entry_size);
 	/* Return key and data */
 	*key = next_key->key;
 	*data = next_key->pdata;
@@ -2607,7 +2606,7 @@ extend_table:
 	}
 	__hash_rw_reader_lock(h);
 	next_key = (struct rte_hash_key *) ((char *)h->key_store +
-				position * h->key_entry_size);
+				position * (size_t)h->key_entry_size);
 	/* Return key and data */
 	*key = next_key->key;
 	*data = next_key->pdata;
-- 
2.47.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-03-19 22:00:48.073840818 +0000
+++ 0007-hash-fix-overflow-of-32-bit-offsets.patch	2026-03-19 22:00:47.766359371 +0000
@@ -1 +1 @@
-From 476a0536b004984e47bd49e36e99949a8b95c701 Mon Sep 17 00:00:00 2001
+From 8dad78c4619b5abdab14d5be9ad15f4810744fdf Mon Sep 17 00:00:00 2001
@@ -8,0 +9,2 @@
+[ upstream commit 476a0536b004984e47bd49e36e99949a8b95c701 ]
+
@@ -24 +25,0 @@
-Cc: stable at dpdk.org
@@ -33 +34 @@
-index da12825c6e..3f382dd117 100644
+index 9575e8aa0c..03bf2ab356 100644
@@ -36 +37 @@
-@@ -705,7 +705,7 @@ rte_hash_reset(struct rte_hash *h)
+@@ -681,7 +681,7 @@ rte_hash_reset(struct rte_hash *h)
@@ -45 +46 @@
-@@ -774,7 +774,7 @@ search_and_update(const struct rte_hash *h, void *data, const void *key,
+@@ -750,7 +750,7 @@ search_and_update(const struct rte_hash *h, void *data, const void *key,
@@ -54 +55 @@
-@@ -1140,7 +1140,7 @@ __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
+@@ -1116,7 +1116,7 @@ __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
@@ -63 +64 @@
-@@ -1329,7 +1329,7 @@ search_one_bucket_l(const struct rte_hash *h, const void *key,
+@@ -1301,7 +1301,7 @@ search_one_bucket_l(const struct rte_hash *h, const void *key,
@@ -72 +73 @@
-@@ -1367,7 +1367,7 @@ search_one_bucket_lf(const struct rte_hash *h, const void *key, uint16_t sig,
+@@ -1339,7 +1339,7 @@ search_one_bucket_lf(const struct rte_hash *h, const void *key, uint16_t sig,
@@ -81 +82 @@
-@@ -1569,7 +1569,7 @@ __hash_rcu_qsbr_free_resource(void *p, void *e, unsigned int n)
+@@ -1537,7 +1537,7 @@ __hash_rcu_qsbr_free_resource(void *p, void *e, unsigned int n)
@@ -90 +91 @@
-@@ -1757,7 +1757,7 @@ search_and_remove(const struct rte_hash *h, const void *key,
+@@ -1721,7 +1721,7 @@ search_and_remove(const struct rte_hash *h, const void *key,
@@ -99 +100 @@
-@@ -1912,8 +1912,7 @@ rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
+@@ -1873,8 +1873,7 @@ rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
@@ -109 +110 @@
-@@ -2007,7 +2006,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
+@@ -1967,7 +1966,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
@@ -118 +119 @@
-@@ -2021,7 +2020,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
+@@ -1981,7 +1980,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
@@ -127 +128 @@
-@@ -2046,7 +2045,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
+@@ -2006,7 +2005,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
@@ -136 +137 @@
-@@ -2074,7 +2073,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
+@@ -2034,7 +2033,7 @@ __bulk_lookup_l(const struct rte_hash *h, const void **keys,
@@ -145 +146 @@
-@@ -2193,7 +2192,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
+@@ -2153,7 +2152,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
@@ -154 +155 @@
-@@ -2207,7 +2206,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
+@@ -2167,7 +2166,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
@@ -163 +164 @@
-@@ -2233,7 +2232,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
+@@ -2193,7 +2192,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
@@ -172 +173 @@
-@@ -2265,7 +2264,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
+@@ -2225,7 +2224,7 @@ __bulk_lookup_lf(const struct rte_hash *h, const void **keys,
@@ -181 +182 @@
-@@ -2621,7 +2620,7 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32
+@@ -2576,7 +2575,7 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32
@@ -190 +191 @@
-@@ -2652,7 +2651,7 @@ extend_table:
+@@ -2607,7 +2606,7 @@ extend_table:


More information about the stable mailing list