From 8c8dfd6686a3d4cc11c20a09c8dfbc8321b07cdb Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 13 Aug 2021 21:13:09 +0200 Subject: [PATCH] Avoid warnings from -fsanitize=integer in the hash functions. Hash functions rely heavily on unsigned integer overflow behavior, but the sanitizer complains about them. Instead of disabling the sanitizer (which might prevent us from getting warnings from real errors), silence it by explicitly upcasting values to 64-bit integers before applying operations, then explicitly downcasting to 32-bit again. The compiler will optimize this out. --- src/subnet.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/subnet.c b/src/subnet.c index 8c766378..ffc82a69 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -40,6 +40,14 @@ splay_tree_t subnet_tree = { /* Subnet lookup cache */ +static uint32_t wrapping_add32(uint32_t a, uint32_t b) { + return (uint32_t)((uint64_t)a + b); +} + +static uint32_t wrapping_mul32(uint32_t a, uint32_t b) { + return (uint32_t)((uint64_t)a * b); +} + static uint32_t hash_function_ipv4_t(const ipv4_t *p) { /* This basic hash works because @@ -51,7 +59,7 @@ static uint32_t hash_function_ipv4_t(const ipv4_t *p) { #if __BYTE_ORDER == __LITTLE_ENDIAN // 10.0.x.x/16 part - hash += halfwidth[1] * 0x9e370001UL; + hash = wrapping_add32(hash, wrapping_mul32(halfwidth[1], 0x9e370001U)); // x.x.0.[0-255] part #if SUBNET_HASH_SIZE >= 0x10000 @@ -62,7 +70,7 @@ static uint32_t hash_function_ipv4_t(const ipv4_t *p) { #endif // _____LP64_____ #else // 10.0.x.x/16 part - hash += halfwidth[0] * 0x9e370001UL; + hash = wrapping_add32(hash, wrapping_mul32(halfwidth[0], 0x9e370001U)); // x.x.0.[0-255] part (ntohs is nop on big endian) return hash ^ halfwidth[1]; @@ -76,7 +84,7 @@ static uint32_t hash_function_ipv6_t(const ipv6_t *p) { for(int i = 0; i < 4; i++) { hash += fullwidth[i]; - hash *= 0x9e370001UL; + hash = wrapping_mul32(hash, 0x9e370001U); } return hash; @@ -88,7 +96,7 @@ static uint32_t hash_function_mac_t(const mac_t *p) { for(int i = 0; i < 3; i++) { hash += halfwidth[i]; - hash *= 0x9e370001UL; + hash = wrapping_mul32(hash, 0x9e370001U); } return hash; -- 2.20.1