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:
Brandon authored and GitHub committed 2026-09-25 16:39:06 +09:00
1 parent df24981307
commit 32580f5d83
1 file changed
+12 -7
+12 -7
View File
@@ -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;
}