From: Alan Coopersmith Date: Thu, 30 Jul 2020 23:13:04 +0000 (-0700) Subject: Use getrandom() if available in json_c_get_random_seed X-Git-Tag: json-c-0.16-20220414~43^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F651%2Fhead;p=thirdparty%2Fjson-c.git Use getrandom() if available in json_c_get_random_seed Lower overhead than opening & reading from /dev/urandom, and works in chroots and other situtations where /dev/urandom is not available. Falls back to existing methods when kernel doesn't support the syscall. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index c334316d..2333d08f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,7 @@ check_include_file(stdint.h HAVE_STDINT_H) check_include_file(stdlib.h HAVE_STDLIB_H) check_include_file(sys/cdefs.h HAVE_SYS_CDEFS_H) check_include_file(sys/param.h HAVE_SYS_PARAM_H) +check_include_file(sys/random.h HAVE_SYS_RANDOM_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(xlocale.h HAVE_XLOCALE_H) @@ -190,6 +191,9 @@ endif() if (HAVE_SYSLOG_H) check_symbol_exists(vsyslog "syslog.h" HAVE_VSYSLOG) endif() +if (HAVE_SYS_RANDOM_H) + check_symbol_exists(getrandom "sys/random.h" HAVE_GETRANDOM) +endif() if (HAVE_SYS_RESOURCE_H) check_symbol_exists(getrusage "sys/resource.h" HAVE_GETRUSAGE) endif() diff --git a/cmake/config.h.in b/cmake/config.h.in index 547a5854..9e097cba 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -56,6 +56,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_PARAM_H @HAVE_SYS_PARAM_H@ +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_RANDOM_H + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_RESOURCE_H @@ -140,6 +143,9 @@ /* Define to 1 if you have the `vsyslog' function. */ #cmakedefine HAVE_VSYSLOG @HAVE_VSYSLOG@ +/* Define if you have the `getrandom' function. */ +#cmakedefine HAVE_GETRANDOM + /* Define if you have the `getrusage' function. */ #cmakedefine HAVE_GETRUSAGE diff --git a/random_seed.c b/random_seed.c index 1a15350c..17727c6a 100644 --- a/random_seed.c +++ b/random_seed.c @@ -155,6 +155,40 @@ retry: #endif /* defined ENABLE_RDRAND */ +#ifdef HAVE_GETRANDOM + +#include +#ifdef HAVE_SYS_RANDOM_H +#include +#endif + +static int get_getrandom_seed(void) +{ + DEBUG_SEED("get_dev_random_seed"); + + int r; + ssize_t ret; + + do { + ret = getrandom(&r, sizeof(r), 0); + } while ((ret == -1) && (errno == EINTR)); + + if (ret == -1) + { + if (errno == ENOSYS) /* syscall not available in kernel */ + return -1; + + fprintf(stderr, "error from getrandom(): %s", strerror(errno)); + exit(1); + } + + if (ret != sizeof(r)) + return -1; + + return r; +} +#endif /* defined HAVE_GETRANDOM */ + /* has_dev_urandom */ #if defined(__APPLE__) || defined(__unix__) || defined(__linux__) @@ -283,6 +317,13 @@ int json_c_get_random_seed(void) if (has_rdrand()) return get_rdrand_seed(); #endif +#ifdef HAVE_GETRANDOM + { + int seed = get_getrandom_seed(); + if (seed != -1) + return seed; + } +#endif #if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM if (has_dev_urandom()) return get_dev_random_seed();