From 7c15b08a7e2a0295ff90d78537a3187a0bbd1712 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 25 Apr 2025 13:49:00 +0200 Subject: [PATCH] lib: hash: murmur3: Account for unaligned 32-bit access The code was casting a byte array to 32-bit words without accounting for alignment. On some platforms (e.g. Arm Cortex-M with multiple load/store instructions) this will fault. Fix it by using the UNALIGED_GET() macro whenever the array is passed unaligned. Signed-off-by: Carles Cufi --- lib/hash/hash_func32_murmur3.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/hash/hash_func32_murmur3.c b/lib/hash/hash_func32_murmur3.c index ff347c982f3..fa758354752 100644 --- a/lib/hash/hash_func32_murmur3.c +++ b/lib/hash/hash_func32_murmur3.c @@ -6,6 +6,8 @@ #include #include +#include +#include static inline uint32_t murmur_32_scramble(uint32_t k) { @@ -16,6 +18,14 @@ static inline uint32_t murmur_32_scramble(uint32_t k) return k; } +#define _LOOP(_GET) \ + for (; n >= sizeof(uint32_t); n -= sizeof(uint32_t), str += sizeof(uint32_t)) { \ + k = _GET; \ + h ^= murmur_32_scramble(k); \ + h = (h << 13) | (h >> 19); \ + h = h * 5 + 0xe6546b64; \ + } + uint32_t sys_hash32_murmur3(const char *str, size_t n) { uint32_t k; @@ -23,11 +33,10 @@ uint32_t sys_hash32_murmur3(const char *str, size_t n) uint32_t h = 0; const size_t len = n; - for (; n >= sizeof(uint32_t); n -= sizeof(uint32_t), str += sizeof(uint32_t)) { - k = *(const uint32_t *)str; - h ^= murmur_32_scramble(k); - h = (h << 13) | (h >> 19); - h = h * 5 + 0xe6546b64; + if (IS_ALIGNED(str, sizeof(uint32_t))) { + _LOOP(*(const uint32_t *)str); + } else { + _LOOP(UNALIGNED_GET((const uint32_t *)str)); } for (k = 0; n != 0; --n, ++str) {