Skip to content

Commit 7a078d2

Browse files
captain5050borkmann
authored andcommitted
libbpf, hashmap: Fix undefined behavior in hash_bits
If bits is 0, the case when the map is empty, then the >> is the size of the register which is undefined behavior - on x86 it is the same as a shift by 0. Fix by handling the 0 case explicitly and guarding calls to hash_bits for empty maps in hashmap__for_each_key_entry and hashmap__for_each_entry_safe. Fixes: e3b9242 ("libbpf: add resizable non-thread safe internal hashmap") Suggested-by: Andrii Nakryiko <[email protected]>, Signed-off-by: Ian Rogers <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 080b6f4 commit 7a078d2

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

tools/lib/bpf/hashmap.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
static inline size_t hash_bits(size_t h, int bits)
1616
{
1717
/* shuffle bits and return requested number of upper bits */
18+
if (bits == 0)
19+
return 0;
20+
1821
#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
1922
/* LP64 case */
2023
return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
@@ -174,17 +177,17 @@ bool hashmap__find(const struct hashmap *map, const void *key, void **value);
174177
* @key: key to iterate entries for
175178
*/
176179
#define hashmap__for_each_key_entry(map, cur, _key) \
177-
for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
178-
map->cap_bits); \
179-
map->buckets ? map->buckets[bkt] : NULL; }); \
180+
for (cur = map->buckets \
181+
? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
182+
: NULL; \
180183
cur; \
181184
cur = cur->next) \
182185
if (map->equal_fn(cur->key, (_key), map->ctx))
183186

184187
#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
185-
for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
186-
map->cap_bits); \
187-
cur = map->buckets ? map->buckets[bkt] : NULL; }); \
188+
for (cur = map->buckets \
189+
? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
190+
: NULL; \
188191
cur && ({ tmp = cur->next; true; }); \
189192
cur = tmp) \
190193
if (map->equal_fn(cur->key, (_key), map->ctx))

0 commit comments

Comments
 (0)