summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <[email protected]>2019-08-05 11:22:49 +0200
committerTomeu Vizoso <[email protected]>2019-08-08 07:42:52 +0200
commit5804d75b9c413ddac8f5f5ada6043b5ee854e3d3 (patch)
tree77771702ef50d6c44a6c5836d14110062e43401c
parentaba57b11ee8c6d4be225f6e22ae00d96b1833d73 (diff)
util/hash_table: Fix hashing in clears on 32-bit
Some hash functions (eg. key_u64_hash) will attempt to dereference the key, causing an invalid access when passed DELETED_KEY_VALUE (0x1) or FREED_KEY_VALUE (0x0). When in 32-bit arch a 64-bit key value doesn't fit into a pointer, so hash_table_u64 internally use a pointer to a struct containing the 64-bit key value. Fix _mesa_hash_table_u64_clear() to handle the 32-bit case by creating a temporary hash_key_u64 to pass to the hash function. Signed-off-by: Tomeu Vizoso <[email protected]> Suggested-by: Caio Marcelo de Oliveira Filho <[email protected]> Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]> Cc: Samuel Pitoiset <[email protected]> Cc: Nicolai Hähnle <[email protected]>
-rw-r--r--src/util/hash_table.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/util/hash_table.c b/src/util/hash_table.c
index f58575de558..58e6fc2d916 100644
--- a/src/util/hash_table.c
+++ b/src/util/hash_table.c
@@ -667,7 +667,12 @@ _mesa_hash_table_u64_clear(struct hash_table_u64 *ht,
struct hash_entry entry;
/* Create a fake entry for the delete function. */
- entry.hash = table->key_hash_function(table->deleted_key);
+ if (sizeof(void *) == 8) {
+ entry.hash = table->key_hash_function(table->deleted_key);
+ } else {
+ struct hash_key_u64 _key = { .value = (uintptr_t)table->deleted_key };
+ entry.hash = table->key_hash_function(&_key);
+ }
entry.key = table->deleted_key;
entry.data = ht->deleted_key_data;
@@ -682,7 +687,12 @@ _mesa_hash_table_u64_clear(struct hash_table_u64 *ht,
struct hash_entry entry;
/* Create a fake entry for the delete function. */
- entry.hash = table->key_hash_function(uint_key(FREED_KEY_VALUE));
+ if (sizeof(void *) == 8) {
+ entry.hash = table->key_hash_function(uint_key(FREED_KEY_VALUE));
+ } else {
+ struct hash_key_u64 _key = { .value = (uintptr_t)FREED_KEY_VALUE };
+ entry.hash = table->key_hash_function(&_key);
+ }
entry.key = uint_key(FREED_KEY_VALUE);
entry.data = ht->freed_key_data;