Prefer getentropy() over arc4random() to seed the string hash (#3629)
glibc's arc4random() aborts with "Fatal glibc error: cannot get entropy
for arc4random" when the kernel lacks getrandom(2), so jq died on
startup on older kernels once 0c7d133 began seeding the hash on every
run. getentropy() merely returns -1/ENOSYS there, so prefer it, and
route its failure through the existing `/dev/urandom` path - which works
on precisely those kernels -- instead of a guessable `getpid() ^ time()`.
This commit is contained in:
1 parent
df24981307
commit
32580f5d83
1 file changed
+12
-7
@@ -1210,12 +1210,18 @@ 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
|
||||
/* Prefer getentropy() over arc4random(): glibc's arc4random() aborts the
|
||||
* process when the kernel lacks getrandom(2) (#3584), while getentropy()
|
||||
* merely fails, letting us fall back to /dev/urandom. */
|
||||
#if defined(HAVE_GETENTROPY)
|
||||
if (getentropy(&seed, sizeof(seed)) == 0) {
|
||||
hash_seed = seed;
|
||||
return;
|
||||
}
|
||||
#elif defined(HAVE_ARC4RANDOM)
|
||||
hash_seed = arc4random();
|
||||
return;
|
||||
#endif
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
if (read(fd, &seed, sizeof(seed)) != 4)
|
||||
@@ -1224,7 +1230,6 @@ static void jvp_hash_seed_init(void) {
|
||||
} else {
|
||||
seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
|
||||
}
|
||||
#endif
|
||||
hash_seed = seed;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user