Skip to content

Commit b814da8

Browse files
committed
system: use getrandom() and fallback on urandom if syscall doesn't work
1 parent 05108ed commit b814da8

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

src/common/System.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636
#include <fcntl.h>
3737
#include <signal.h>
3838
#ifdef __linux__
39-
#include <linux/version.h>
40-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
41-
#include <sys/syscall.h>
42-
#include <linux/random.h>
43-
#define HAS_GETRANDOM_SYSCALL 1
44-
#endif
39+
#include <sys/random.h>
4540
#endif
4641
#ifdef __native_client__
4742
#include <nacl/nacl_exception.h>
@@ -410,19 +405,32 @@ void GenRandomBytes(void* dest, size_t size)
410405
size_t bytes_written;
411406
if (nacl_secure_random(dest, size, &bytes_written) != 0 || bytes_written != size)
412407
Sys::Error("nacl_secure_random failed");
413-
#elif defined(__linux__) && defined(HAS_GETRANDOM_SYSCALL)
414-
if (syscall(SYS_getrandom, dest, size, GRND_NONBLOCK) == -1)
415-
Sys::Error("Failed getrandom syscall: %s", strerror(errno));
416408
#elif defined(__linux__)
417-
int fd = open("/dev/urandom", O_RDONLY);
418-
if (fd == -1)
419-
Sys::Error("Failed to open /dev/urandom: %s", strerror(errno));
420-
if (read(fd, dest, size) != (ssize_t) size)
421-
Sys::Error("Failed to read from /dev/urandom: %s", strerror(errno));
422-
close(fd);
409+
ssize_t ret = getrandom(dest, size, GRND_NONBLOCK);
410+
if (ret == -1)
411+
{
412+
if (errno == ENOSYS)
413+
{
414+
Log::Warn("Failed getrandom syscall: %s", strerror(ENOSYS));
415+
416+
int fd = open("/dev/urandom", O_RDONLY);
417+
if (fd == -1)
418+
Sys::Error("Failed to open /dev/urandom: %s", strerror(errno));
419+
if (read(fd, dest, size) != (ssize_t) size)
420+
Sys::Error("Failed to read from /dev/urandom: %s", strerror(errno));
421+
close(fd);
422+
}
423+
else
424+
{
425+
Sys::Error("Failed getrandom syscall: %s", strerror(errno));
426+
}
427+
}
428+
else if (ret != size)
429+
{
430+
Sys::Error("Failed getrandom syscall: %s", strerror(EAGAIN));
431+
}
423432
#else
424433
arc4random_buf(dest, size);
425-
426434
#endif
427435
}
428436

0 commit comments

Comments
 (0)