Skip to content

Commit 5472927

Browse files
committed
Cleanup how the initial hash value is seeded
1 parent e380a94 commit 5472927

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

src/bin/tools/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ else ()
66
mimegen.c
77
${CMAKE_SOURCE_DIR}/src/lib/hash.c
88
${CMAKE_SOURCE_DIR}/src/lib/missing.c
9+
${CMAKE_SOURCE_DIR}/src/lib/lwan-status.c
910
)
1011
if (LWAN_HAVE_BROTLI)
1112
message(STATUS "Using Brotli for mimegen")

src/lib/hash.c

+33-15
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,22 @@ struct hash_entry {
8080
static_assert((MIN_BUCKETS & (MIN_BUCKETS - 1)) == 0,
8181
"Bucket size is power of 2");
8282

83+
#define DEFAULT_FNV1A_64_SEED 0xcbf29ce484222325ull
84+
#define DEFAULT_FNV1A_32_SEED 0x811c9dc5u
85+
86+
uint64_t fnv1a_64_seed = DEFAULT_FNV1A_64_SEED;
87+
uint32_t fnv1a_32_seed = DEFAULT_FNV1A_32_SEED;
88+
89+
#define ASSERT_SEED_INITIALIZED() \
90+
do { \
91+
assert(fnv1a_64_seed != DEFAULT_FNV1A_64_SEED); \
92+
assert(fnv1a_32_seed != DEFAULT_FNV1A_32_SEED); \
93+
} while (0)
94+
8395
static inline unsigned int hash_fnv1a_32(const void *keyptr);
8496
static inline unsigned int hash_int_32(const void *keyptr);
8597
static inline unsigned int hash_int_64(const void *keyptr);
8698

87-
static unsigned int odd_constant = DEFAULT_ODD_CONSTANT;
8899
static unsigned (*hash_str)(const void *key) = hash_fnv1a_32;
89100
static unsigned (*hash_int)(const void *key) = hash_int_32;
90101
static unsigned (*hash_int64)(const void *key) = hash_int_64;
@@ -135,10 +146,12 @@ static inline unsigned int hash_int_64(const void *keyptr)
135146
#if defined(LWAN_HAVE_BUILTIN_CPU_INIT) && defined(LWAN_HAVE_BUILTIN_IA32_CRC32)
136147
static inline unsigned int hash_str_crc32(const void *keyptr)
137148
{
138-
unsigned int hash = odd_constant;
149+
unsigned int hash = fnv1a_32_seed;
139150
const char *key = keyptr;
140151
size_t len = strlen(key);
141152

153+
ASSERT_SEED_INITIALIZED();
154+
142155
#if __x86_64__
143156
while (len >= sizeof(uint64_t)) {
144157
uint64_t data;
@@ -171,20 +184,24 @@ static inline unsigned int hash_str_crc32(const void *keyptr)
171184

172185
static inline unsigned int hash_int_crc32(const void *keyptr)
173186
{
174-
return __builtin_ia32_crc32si(odd_constant,
187+
ASSERT_SEED_INITIALIZED();
188+
189+
return __builtin_ia32_crc32si(fnv1a_32_seed,
175190
(unsigned int)(uintptr_t)keyptr);
176191
}
177192

178193
static inline unsigned int hash_int64_crc32(const void *keyptr)
179194
{
195+
ASSERT_SEED_INITIALIZED();
196+
180197
#ifdef __x86_64__
181-
return (unsigned int)__builtin_ia32_crc32di(odd_constant,
198+
return (unsigned int)__builtin_ia32_crc32di(fnv1a_32_seed,
182199
(uint64_t)(uintptr_t)keyptr);
183200
#else
184201
const uint64_t key = (uint64_t)(uintptr_t)keyptr;
185202
uint32_t crc;
186203

187-
crc = __builtin_ia32_crc32si(odd_constant, (uint32_t)(key & 0xffffffff));
204+
crc = __builtin_ia32_crc32si(fnv1a_32_seed, (uint32_t)(key & 0xffffffff));
188205
crc = __builtin_ia32_crc32si(crc, (uint32_t)(key >> 32));
189206

190207
return crc;
@@ -193,19 +210,20 @@ static inline unsigned int hash_int64_crc32(const void *keyptr)
193210

194211
#endif
195212

196-
uint64_t fnv1a_64_seed = 0xcbf29ce484222325ull;
197-
uint32_t fnv1a_32_seed = 0x811c9dc5u;
198-
199-
__attribute__((constructor(65535))) static void initialize_odd_constant(void)
213+
__attribute__((constructor(65535))) static void initialize_fnv1a_seed(void)
200214
{
201-
/* This constant is randomized in order to mitigate the DDoS attack
215+
uint8_t entropy[128];
216+
217+
/* The seeds are randomized in order to mitigate the DDoS attack
202218
* described by Crosby and Wallach in UsenixSec2003. */
203-
if (lwan_getentropy(&odd_constant, sizeof(odd_constant), 0) < 0)
204-
odd_constant = DEFAULT_ODD_CONSTANT;
205-
odd_constant |= 1;
219+
if (UNLIKELY(lwan_getentropy(entropy, sizeof(entropy), 0) < 0)) {
220+
lwan_status_perror("Could not initialize FNV1a seed");
221+
__builtin_unreachable();
222+
}
206223

207-
fnv1a_64_seed = fnv1a_64(&odd_constant, sizeof(odd_constant));
208-
fnv1a_32_seed = fnv1a_32(&odd_constant, sizeof(odd_constant));
224+
fnv1a_64_seed = fnv1a_64(entropy, sizeof(entropy));
225+
fnv1a_32_seed = fnv1a_32(entropy, sizeof(entropy));
226+
lwan_always_bzero(entropy, sizeof(entropy));
209227

210228
#if defined(LWAN_HAVE_BUILTIN_CPU_INIT) && defined(LWAN_HAVE_BUILTIN_IA32_CRC32)
211229
__builtin_cpu_init();

0 commit comments

Comments
 (0)