Index: include/stdlib.h =================================================================== --- include/stdlib.h +++ include/stdlib.h @@ -254,12 +254,6 @@ __uint32_t arc4random_uniform(__uint32_t); -#if !defined(BURN_BRIDGES) -/* Deprecated arc4random() functions */ -#define arc4random_stir() -#define arc4random_addrandom(a,b) -#endif - #ifdef __BLOCKS__ int atexit_b(void (^ _Nonnull)(void)); void *bsearch_b(const void *, const void *, size_t, Index: lib/libc/gen/getentropy.c =================================================================== --- lib/libc/gen/getentropy.c +++ lib/libc/gen/getentropy.c @@ -34,10 +34,14 @@ #include #include +#include #include #include "libc_private.h" +/* First __FreeBSD_version bump after introduction of getrandom(2) (r331279) */ +#define GETRANDOM_FIRST 1200061 + extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t); static size_t @@ -99,21 +103,38 @@ getentropy(void *buf, size_t buflen) { ssize_t rd; + bool have_getrandom; if (buflen > 256) { errno = EIO; return (-1); } + have_getrandom = (__getosreldate() >= GETRANDOM_FIRST); + while (buflen > 0) { - rd = getrandom(buf, buflen, 0); - if (rd == -1) { - if (errno == EINTR) - continue; - else if (errno == ENOSYS || errno == ECAPMODE) - return (getentropy_fallback(buf, buflen)); - else - return (-1); + if (have_getrandom) { + rd = getrandom(buf, buflen, 0); + if (rd == -1) { + switch (errno) { + case ECAPMODE: + /* + * Kernel >= r331280 and < r337999 + * will return ECAPMODE when the + * caller is already in capability + * mode, fallback to traditional + * method in this case. + */ + have_getrandom = false; + continue; + case EINTR: + continue; + default: + return (-1); + } + } + } else { + return (getentropy_fallback(buf, buflen)); } /* This cannot happen. */