From: Yipeng Wang Date: Mon, 22 Oct 2018 18:39:45 +0000 (-0700) Subject: hash: fix race condition in iterate X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=99040943442426ebfef0ad69eca73559a9e3b730;p=dpdk.git hash: fix race condition in iterate In rte_hash_iterate, the reader lock did not protect the while loop which checks empty entry. This created a race condition that the entry may become empty when enters the lock, then a wrong key data value would be read out. This commit reads out the position in the while condition, which makes sure that the position will not be changed to empty before entering the lock. Fixes: f2e3001b53ec ("hash: support read/write concurrency") Cc: stable@dpdk.org Reported-by: Honnappa Nagarahalli Signed-off-by: Yipeng Wang Reviewed-by: Honnappa Nagarahalli Acked-by: Dharmik Thakkar Acked-by: Bruce Richardson --- diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c index f7b86c8c95..da8ddf40a5 100644 --- a/lib/librte_hash/rte_cuckoo_hash.c +++ b/lib/librte_hash/rte_cuckoo_hash.c @@ -1318,7 +1318,7 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32 idx = *next % RTE_HASH_BUCKET_ENTRIES; /* If current position is empty, go to the next one */ - while (h->buckets[bucket_idx].key_idx[idx] == EMPTY_SLOT) { + while ((position = h->buckets[bucket_idx].key_idx[idx]) == EMPTY_SLOT) { (*next)++; /* End of table */ if (*next == total_entries) @@ -1326,9 +1326,8 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32 bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES; idx = *next % RTE_HASH_BUCKET_ENTRIES; } + __hash_rw_reader_lock(h); - /* Get position of entry in key table */ - position = h->buckets[bucket_idx].key_idx[idx]; next_key = (struct rte_hash_key *) ((char *)h->key_store + position * h->key_entry_size); /* Return key and data */