Randomize hash seed to mitigate hash collision DoS attacks
The hash function used a fixed seed, allowing attackers to craft colliding keys and cause O(n^2) object parsing performance. Initialize the seed from a random source at process startup to prevent the attack. This fixes CVE-2026-40164. Co-authored-by: Asaf Meizner <asafmeizner@gmail.com>
This commit is contained in:
1 parent
6374ae0bcd
commit
0c7d133c3c
2 files changed
+34
-2
No files matched your search
@@ -149,6 +149,8 @@ AC_CHECK_MEMBER([struct tm.tm_gmtoff], [AC_DEFINE([HAVE_TM_TM_GMT_OFF],1,[Define
|
|||||||
AC_CHECK_MEMBER([struct tm.__tm_gmtoff], [AC_DEFINE([HAVE_TM___TM_GMT_OFF],1,[Define to 1 if the system has the __tm_gmt_off field in struct tm])],
|
AC_CHECK_MEMBER([struct tm.__tm_gmtoff], [AC_DEFINE([HAVE_TM___TM_GMT_OFF],1,[Define to 1 if the system has the __tm_gmt_off field in struct tm])],
|
||||||
[], [[#include <time.h>]])
|
[], [[#include <time.h>]])
|
||||||
AC_FIND_FUNC([setlocale], [c], [#include <locale.h>], [0,0])
|
AC_FIND_FUNC([setlocale], [c], [#include <locale.h>], [0,0])
|
||||||
|
AC_FIND_FUNC([arc4random], [c], [#include <stdlib.h>], [])
|
||||||
|
AC_FIND_FUNC([getentropy], [c], [#include <unistd.h>], [0, 0])
|
||||||
|
|
||||||
dnl Figure out if we have the pthread functions we actually need
|
dnl Figure out if we have the pthread functions we actually need
|
||||||
AC_FIND_FUNC_NO_LIBS([pthread_key_create], [], [#include <pthread.h>], [NULL, NULL])
|
AC_FIND_FUNC_NO_LIBS([pthread_key_create], [], [#include <pthread.h>], [NULL, NULL])
|
||||||
|
|||||||
@@ -40,6 +40,10 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "jv_alloc.h"
|
#include "jv_alloc.h"
|
||||||
#include "jv.h"
|
#include "jv.h"
|
||||||
@@ -1206,7 +1210,33 @@ static jv jvp_string_append(jv string, const char* data, uint32_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t HASH_SEED = 0x432A9843;
|
static uint32_t hash_seed;
|
||||||
|
static pthread_once_t hash_seed_once = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
|
static void jvp_hash_seed_init(void) {
|
||||||
|
uint32_t seed;
|
||||||
|
#if defined(HAVE_ARC4RANDOM)
|
||||||
|
seed = arc4random();
|
||||||
|
#elif defined(HAVE_GETENTROPY)
|
||||||
|
if (getentropy(&seed, sizeof(seed)) != 0)
|
||||||
|
seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
|
||||||
|
#else
|
||||||
|
int fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (fd >= 0) {
|
||||||
|
if (read(fd, &seed, sizeof(seed)) != 4)
|
||||||
|
seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
|
||||||
|
close(fd);
|
||||||
|
} else {
|
||||||
|
seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
hash_seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t jvp_hash_seed(void) {
|
||||||
|
pthread_once(&hash_seed_once, jvp_hash_seed_init);
|
||||||
|
return hash_seed;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t rotl32 (uint32_t x, int8_t r){
|
static uint32_t rotl32 (uint32_t x, int8_t r){
|
||||||
return (x << r) | (x >> (32 - r));
|
return (x << r) | (x >> (32 - r));
|
||||||
@@ -1225,7 +1255,7 @@ static uint32_t jvp_string_hash(jv jstr) {
|
|||||||
int len = (int)jvp_string_length(str);
|
int len = (int)jvp_string_length(str);
|
||||||
const int nblocks = len / 4;
|
const int nblocks = len / 4;
|
||||||
|
|
||||||
uint32_t h1 = HASH_SEED;
|
uint32_t h1 = jvp_hash_seed();
|
||||||
|
|
||||||
const uint32_t c1 = 0xcc9e2d51;
|
const uint32_t c1 = 0xcc9e2d51;
|
||||||
const uint32_t c2 = 0x1b873593;
|
const uint32_t c2 = 0x1b873593;
|
||||||
|
|||||||
Reference in new issue
Block a user