Skip to content

Commit c352bd0

Browse files
Fix seeding from random device w/o getrandom syscall
Use select to wait for /dev/random in readable state, but do not actually read anything from /dev/random, use /dev/urandom first. Use linux define __NR_getrandom instead of the glibc define SYS_getrandom, in case the kernel headers are more current than the glibc headers. Fixes #8215 Reviewed-by: Kurt Roeckx <[email protected]> (Merged from #8251) (cherry picked from commit 38023b8)
1 parent de4fb43 commit c352bd0

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

crypto/rand/rand_unix.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <stdio.h>
2020
#include "internal/dso.h"
2121
#if defined(__linux)
22-
# include <sys/syscall.h>
22+
# include <asm/unistd.h>
2323
#endif
2424
#if defined(__FreeBSD__)
2525
# include <sys/types.h>
@@ -324,8 +324,8 @@ static ssize_t syscall_random(void *buf, size_t buflen)
324324
# endif
325325

326326
/* Linux supports this since version 3.17 */
327-
# if defined(__linux) && defined(SYS_getrandom)
328-
return syscall(SYS_getrandom, buf, buflen, 0);
327+
# if defined(__linux) && defined(__NR_getrandom)
328+
return syscall(__NR_getrandom, buf, buflen, 0);
329329
# elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
330330
return sysctl_random(buf, buflen);
331331
# else
@@ -510,6 +510,29 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
510510
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
511511
{
512512
size_t i;
513+
#ifdef DEVRANDOM_WAIT
514+
static int wait_done = 0;
515+
516+
/*
517+
* On some implementations reading from /dev/urandom is possible
518+
* before it is initialized. Therefore we wait for /dev/random
519+
* to be readable to make sure /dev/urandom is initialized.
520+
*/
521+
if (!wait_done && bytes_needed > 0) {
522+
int f = open(DEVRANDOM_WAIT, O_RDONLY);
523+
524+
if (f >= 0) {
525+
fd_set fds;
526+
527+
FD_ZERO(&fds);
528+
FD_SET(f, &fds);
529+
while (select(f+1, &fds, NULL, NULL, NULL) < 0
530+
&& errno == EINTR);
531+
close(f);
532+
}
533+
wait_done = 1;
534+
}
535+
#endif
513536

514537
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) {
515538
ssize_t bytes = 0;

e_os.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@
2727
* set this to a comma-separated list of 'random' device files to try out. By
2828
* default, we will try to read at least one of these files
2929
*/
30-
# if defined(__s390__)
31-
# define DEVRANDOM "/dev/prandom","/dev/urandom","/dev/hwrng","/dev/random"
32-
# else
33-
# define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
34-
# endif
30+
# define DEVRANDOM "/dev/urandom", "/dev/random", "/dev/hwrng", "/dev/srandom"
31+
# define DEVRANDOM_WAIT "/dev/random"
3532
# endif
3633
# if !defined(OPENSSL_NO_EGD) && !defined(DEVRANDOM_EGD)
3734
/*
3835
* set this to a comma-separated list of 'egd' sockets to try out. These
3936
* sockets will be tried in the order listed in case accessing the device
4037
* files listed in DEVRANDOM did not return enough randomness.
4138
*/
42-
# define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"
39+
# define DEVRANDOM_EGD "/var/run/egd-pool", "/dev/egd-pool", "/etc/egd-pool", "/etc/entropy"
4340
# endif
4441

4542
# if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)

0 commit comments

Comments
 (0)