Use getentropy() for seeding PRNG in Perl_seed()

On libc (*nix) systems we call `getentropy()` to get the seed needed to
start the PRNG. If that call fails, we fall back to reading the
filesystem via `/dev/urandom`. If that fails we fall back to hashing
some state variables instead.

This should be faster, less risky, and generally better than trying to
read from `/dev/urandom`

Foo
This commit is contained in:
Scott Baker 2026-01-22 10:07:22 -08:00 committed by Karl Williamson
parent d4247bb256
commit 8d1c2aec21
11 changed files with 53 additions and 0 deletions

View File

@ -519,6 +519,7 @@ d_gai_strerror=''
d_Gconvert=''
d_getaddrinfo=''
d_getcwd=''
d_getentropy=''
d_getenv_preserves_other_thread=''
d_getespwnam=''
d_getfsstat=''
@ -702,6 +703,7 @@ d_newlocale=''
d_querylocale=''
d_uselocale=''
i_xlocale=''
i_sysrandom=''
xlocale_needed=''
d_nextafter=''
d_nexttoward=''
@ -12759,6 +12761,10 @@ eval $inlibc
set xlocale.h i_xlocale
eval $inhdr
: see if this is a sys/random.h system
set sys/random.h i_sysrandom
eval $inhdr
: see if newlocale exists
set newlocale d_newlocale
eval $inlibc
@ -14369,6 +14375,10 @@ eval $inlibc
set getcwd d_getcwd
eval $inlibc
: see if getentropy exists
set getentropy d_getentropy
eval $inlibc
: check for getenv behavior
case "$d_getenv_preserves_other_thread" in
'')
@ -25125,6 +25135,7 @@ d_gdbm_ndbm_h_uses_prototypes='$d_gdbm_ndbm_h_uses_prototypes'
d_gdbmndbm_h_uses_prototypes='$d_gdbmndbm_h_uses_prototypes'
d_getaddrinfo='$d_getaddrinfo'
d_getcwd='$d_getcwd'
d_getentropy='$d_getentropy'
d_getenv_preserves_other_thread='$d_getenv_preserves_other_thread'
d_getespwnam='$d_getespwnam'
d_getfsstat='$d_getfsstat'
@ -25718,6 +25729,7 @@ i_vfork='$i_vfork'
i_wchar='$i_wchar'
i_wctype='$i_wctype'
i_xlocale='$i_xlocale'
i_sysrandom='$i_sysrandom'
ignore_versioned_solibs='$ignore_versioned_solibs'
inc_version_list='$inc_version_list'
inc_version_list_init='$inc_version_list_init'

View File

@ -252,6 +252,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='undef'
d_getcwd='define'
d_getentropy='undef'
d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
@ -808,6 +809,7 @@ i_sysmount='define'
i_sysndir='undef'
i_sysparam='define'
i_syspoll='undef'
i_sysrandom='undef'
i_sysresrc='define'
i_syssecrt='undef'
i_sysselct='define'

View File

@ -251,6 +251,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='undef'
d_getcwd='define'
d_getentropy='undef'
d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
@ -806,6 +807,7 @@ i_sysmount='define'
i_sysndir='undef'
i_sysparam='define'
i_syspoll='undef'
i_sysrandom='undef'
i_sysresrc='define'
i_syssecrt='undef'
i_sysselct='define'

View File

@ -263,6 +263,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='define'
d_getcwd='define'
d_getentropy='undef'
d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
@ -830,6 +831,7 @@ i_sysmount='define'
i_sysndir='undef'
i_sysparam='define'
i_syspoll='define'
i_sysrandom='undef'
i_sysresrc='define'
i_syssecrt='undef'
i_sysselct='define'

View File

@ -561,6 +561,12 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
*/
#$d_system HAS_SYSTEM /**/
/* HAS_SYSRANDOM:
* This symbol, if defined, indicates that the system has the
* sys/random.h header file.
*/
#$i_sysrandom HAS_SYSRANDOM /**/
/* HAS_TCGETPGRP:
* This symbol, if defined, indicates that the tcgetpgrp routine is
* available to get foreground process group ID.
@ -1604,6 +1610,12 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
*/
#$d_flexfnam FLEXFILENAMES /**/
/* HAS_GETENTROPY:
* This symbol, if defined, indicates that the getentropy routine is
* available.
*/
#$d_getentropy HAS_GETENTROPY /**/
/* HAS_GETGRENT:
* This symbol, if defined, indicates that the getgrent routine is
* available for sequential access of the group database.

View File

@ -6210,6 +6210,7 @@ $ WC "d_nice='define'"
$ WC "d_nl_langinfo='" + d_nl_langinfo + "'"
$ WC "d_nl_langinfo_l='undef'"
$ WC "d_non_int_bitfields='define'"
$ WC "d_getentropy='undef'"
$ WC "d_getenv_preserves_other_thread='" + d_getenv_preserves_other_thread + "'"
$ WC "d_nv_preserves_uv='" + d_nv_preserves_uv + "'"
$ WC "nv_overflows_integers_at='" + nv_overflows_integers_at + "'"
@ -6573,6 +6574,7 @@ $ WC "i_sysmount='undef'"
$ WC "i_sysndir='undef'"
$ WC "i_sysparam='undef'"
$ WC "i_syspoll='" + i_syspoll + "'"
$ WC "i_sysrandom='undef'"
$ WC "i_sysresrc='undef'"
$ WC "i_syssecrt='" + i_syssecrt + "'"
$ WC "i_sysselct='undef'"

View File

@ -44,6 +44,7 @@
* HAS_FD_SET
* HAS_FFS
* HAS_FFSL
* HAS_GETENTROPY
* HAS_GETMNT
* HAS_GMTIME64
* HAS_GNULIBC
@ -85,6 +86,7 @@
* INSTALL_USR_BIN_PERL
* I_STDBOOL
* I_SYS_MOUNT
* I_SYSRANDOM
* I_SYS_STATFS
* I_SYS_STATVFS
* I_SYS_VFS

View File

@ -252,6 +252,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='undef'
d_getcwd='define'
d_getentropy='undef'
d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
@ -802,6 +803,7 @@ i_sysmount='undef'
i_sysndir='undef'
i_sysparam='define'
i_syspoll='undef'
i_sysrandom='undef'
i_sysresrc='define'
i_syssecrt='undef'
i_sysselct='define'

13
util.c
View File

@ -38,6 +38,11 @@
#include <math.h>
#include <stdlib.h>
/* For get_entropy() on non-Linux systems (MacOS, Android) we need sys/random.h */
#ifdef HAS_SYSRANDOM
#include <sys/random.h>
#endif
#ifdef __Lynx__
/* Missing protos on LynxOS */
int putenv(char *);
@ -4612,6 +4617,14 @@ Perl_seed(pTHX)
#endif
U64 u;
#ifdef HAS_GETENTROPY
U8 ok = (getentropy(&u, sizeof(u)) == 0);
PerlIO_printf(Perl_debug_log, "Entropy: OK:%i Seed:%lu\n", ok, u);
if (ok) {
return u;
}
#endif
int fd = PerlLIO_open_cloexec(PERL_RANDOM_DEVICE, 0);
if (fd != -1) {
if (PerlLIO_read(fd, (void*)&u, sizeof u) != sizeof u) {

View File

@ -239,6 +239,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='define'
d_getcwd='define'
d_getentropy='undef'
d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
@ -799,6 +800,7 @@ i_sysmount='undef'
i_sysndir='undef'
i_sysparam='undef'
i_syspoll='undef'
i_sysrandom='undef'
i_sysresrc='undef'
i_syssecrt='undef'
i_sysselct='undef'

View File

@ -239,6 +239,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='undef'
d_getcwd='define'
d_getentropy='undef'
d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
@ -798,6 +799,7 @@ i_sysmount='undef'
i_sysndir='undef'
i_sysparam='undef'
i_syspoll='undef'
i_sysrandom='undef'
i_sysresrc='undef'
i_syssecrt='undef'
i_sysselct='undef'