From 5523a505f4bd6ce57f951ccb0cc7b9b29a963d7c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 21 Apr 2023 16:23:39 +0200 Subject: [PATCH] lib: fix _hash_member() crash w/ empty hash The typesafe hash _member() didn't check tabshift/count before proceeding to look at the hash table, leading it to dereference a NULL pointer when the hash table is in fact empty. Test case added to tests/lib/test_typelist. Note this function is not currently used anywhere. Only lib/cspf.c uses _member(), but it does so on a RB-tree rather than a hash. Signed-off-by: David Lamparter --- lib/typesafe.h | 2 ++ tests/lib/test_typelist.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/lib/typesafe.h b/lib/typesafe.h index 66612be167..8eb59c33b7 100644 --- a/lib/typesafe.h +++ b/lib/typesafe.h @@ -948,6 +948,8 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ macro_pure bool prefix ## _member(const struct prefix##_head *h, \ const type *item) \ { \ + if (!h->hh.tabshift) \ + return NULL; \ uint32_t hval = item->field.hi.hashval, hbits = HASH_KEY(h->hh, hval); \ const struct thash_item *hitem = h->hh.entries[hbits]; \ while (hitem && hitem->hashval < hval) \ diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h index 91528139b5..80c4005437 100644 --- a/tests/lib/test_typelist.h +++ b/tests/lib/test_typelist.h @@ -171,6 +171,11 @@ static void concat(test_, TYPE)(void) ts_hash("init", "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"); +#if !IS_ATOMIC(REALTYPE) + assert(!list_member(&head, &itm[0])); + assert(!list_member(&head, &itm[1])); +#endif + #if IS_SORTED(REALTYPE) prng = prng_new(0); k = 0;