mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 22:09:48 +00:00
lib: fix typesafe hash add with hash collision
The typesafe hash data structure enforces items to be unique, but their hash values may still collide. To this extent, when two items have the same hash value, the compare function is called to see if it returns 0 (aka "equal"). While the _find() function handles this correctly, the _add() function mistakenly only checked the first item with a colliding hash value for equality, and if it was inequal proceeded to add the new item. There may however be additional items with the same hash value collision, one of which could still compare as equal. In that case, _add() would mistakenly add the new element, failing to notice the already added item. Breakage ensues. Fix by looking for an equal element among *all* existing items with the same hash value, not just the first. Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com> [DL: rewrote commit message, fixed whitespace/formatting] Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
4b72a7be69
commit
5e0136c94f
@ -850,9 +850,12 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item) \
|
||||
struct thash_item **np = &h->hh.entries[hbits]; \
|
||||
while (*np && (*np)->hashval < hval) \
|
||||
np = &(*np)->next; \
|
||||
if (*np && cmpfn(container_of(*np, type, field.hi), item) == 0) { \
|
||||
h->hh.count--; \
|
||||
return container_of(*np, type, field.hi); \
|
||||
while (*np && (*np)->hashval == hval) { \
|
||||
if (cmpfn(container_of(*np, type, field.hi), item) == 0) { \
|
||||
h->hh.count--; \
|
||||
return container_of(*np, type, field.hi); \
|
||||
} \
|
||||
np = &(*np)->next; \
|
||||
} \
|
||||
item->field.hi.next = *np; \
|
||||
*np = &item->field.hi; \
|
||||
|
Loading…
Reference in New Issue
Block a user