diff options
author | Daiki Ueno <ueno@gnu.org> | 2021-03-11 06:23:03 +0000 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2021-03-11 06:23:03 +0000 |
commit | c95312c5831be5418dc02a86d72bcd1eafd4c145 (patch) | |
tree | d6ef20b98fb962644ed056114f5f22ca5c03d795 | |
parent | 776eeadf468318c4ceb80abe96a8017ab4ae0bc0 (diff) | |
parent | db5e38aec5123b6fa4ad5eed7961adbd83deecba (diff) | |
download | gnutls-c95312c5831be5418dc02a86d72bcd1eafd4c145.tar.gz |
Merge branch 'oneshot-urandom' into 'master'
sysrng-linux: re-open /dev/urandom every time
Closes #1188
See merge request gnutls/gnutls!1396
-rw-r--r-- | lib/global.c | 10 | ||||
-rw-r--r-- | lib/nettle/rnd-common.h | 1 | ||||
-rw-r--r-- | lib/nettle/sysrng-bcrypt.c | 5 | ||||
-rw-r--r-- | lib/nettle/sysrng-getentropy.c | 5 | ||||
-rw-r--r-- | lib/nettle/sysrng-linux.c | 68 | ||||
-rw-r--r-- | lib/nettle/sysrng-netbsd.c | 5 | ||||
-rw-r--r-- | lib/nettle/sysrng-windows.c | 5 | ||||
-rw-r--r-- | lib/random.h | 5 | ||||
-rw-r--r-- | tests/rng-sigint.c | 1 |
9 files changed, 24 insertions, 81 deletions
diff --git a/lib/global.c b/lib/global.c index 9a65d114cc..b41e20a9a0 100644 --- a/lib/global.c +++ b/lib/global.c @@ -236,16 +236,6 @@ static int _gnutls_global_init(unsigned constructor) _gnutls_init++; if (_gnutls_init > 1) { - if (_gnutls_init == 2 && _gnutls_init_ret == 0) { - /* some applications may close the urandom fd - * before calling gnutls_global_init(). in that - * case reopen it */ - ret = _gnutls_rnd_check(); - if (ret < 0) { - gnutls_assert(); - goto out; - } - } ret = _gnutls_init_ret; goto out; } diff --git a/lib/nettle/rnd-common.h b/lib/nettle/rnd-common.h index 429ca017d3..025fe02e8f 100644 --- a/lib/nettle/rnd-common.h +++ b/lib/nettle/rnd-common.h @@ -35,7 +35,6 @@ #include <fips.h> int _rnd_system_entropy_init(void); -int _rnd_system_entropy_check(void); void _rnd_system_entropy_deinit(void); typedef int (*get_entropy_func)(void* rnd, size_t size); diff --git a/lib/nettle/sysrng-bcrypt.c b/lib/nettle/sysrng-bcrypt.c index 10dc9ac83a..a08e9deb92 100644 --- a/lib/nettle/sysrng-bcrypt.c +++ b/lib/nettle/sysrng-bcrypt.c @@ -64,11 +64,6 @@ int _rnd_get_system_entropy_win32(void* rnd, size_t size) return 0; } -int _rnd_system_entropy_check(void) -{ - return 0; -} - int _rnd_system_entropy_init(void) { NTSTATUS err = BCryptOpenAlgorithmProvider diff --git a/lib/nettle/sysrng-getentropy.c b/lib/nettle/sysrng-getentropy.c index 99e95ead8b..0666d482c2 100644 --- a/lib/nettle/sysrng-getentropy.c +++ b/lib/nettle/sysrng-getentropy.c @@ -71,11 +71,6 @@ int _rnd_system_entropy_init(void) return 0; } -int _rnd_system_entropy_check(void) -{ - return 0; -} - void _rnd_system_entropy_deinit(void) { return; diff --git a/lib/nettle/sysrng-linux.c b/lib/nettle/sysrng-linux.c index 2e17ecdd0c..6b3971c65f 100644 --- a/lib/nettle/sysrng-linux.c +++ b/lib/nettle/sysrng-linux.c @@ -46,10 +46,6 @@ #include <sys/time.h> #include <fcntl.h> -static int _gnutls_urandom_fd = -1; -static ino_t _gnutls_urandom_fd_ino = 0; -static dev_t _gnutls_urandom_fd_rdev = 0; - get_entropy_func _rnd_get_system_entropy = NULL; #if defined(__linux__) @@ -127,11 +123,18 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size) { uint8_t* rnd = _rnd; uint32_t done; + int urandom_fd; + + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) { + _gnutls_debug_log("Cannot open /dev/urandom!\n"); + return GNUTLS_E_RANDOM_DEVICE_ERROR; + } for (done = 0; done < size;) { int res; do { - res = read(_gnutls_urandom_fd, rnd + done, size - done); + res = read(urandom_fd, rnd + done, size - done); } while (res < 0 && errno == EINTR); if (res <= 0) { @@ -145,74 +148,51 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size) ("Failed to read /dev/urandom: end of file\n"); } + close(urandom_fd); return GNUTLS_E_RANDOM_DEVICE_ERROR; } done += res; } - return 0; -} - -/* This is called when gnutls_global_init() is called for second time. - * It must check whether any resources are still available. - * The particular problem it solves is to verify that the urandom fd is still - * open (for applications that for some reason closed all fds */ -int _rnd_system_entropy_check(void) -{ - int ret; - struct stat st; - - if (_gnutls_urandom_fd == -1) /* not using urandom */ - return 0; - - ret = fstat(_gnutls_urandom_fd, &st); - if (ret < 0 || st.st_ino != _gnutls_urandom_fd_ino || st.st_rdev != _gnutls_urandom_fd_rdev) { - return _rnd_system_entropy_init(); - } + close(urandom_fd); return 0; } int _rnd_system_entropy_init(void) { - int old; - struct stat st; + int urandom_fd; #if defined(__linux__) /* Enable getrandom() usage if available */ if (have_getrandom()) { _rnd_get_system_entropy = _rnd_get_system_entropy_getrandom; - _gnutls_debug_log("getrandom random generator was detected\n"); + _gnutls_debug_log("getrandom random generator was selected\n"); return 0; + } else { + _gnutls_debug_log("getrandom is not available\n"); } #endif - /* First fallback: /dev/unrandom */ - _gnutls_urandom_fd = open("/dev/urandom", O_RDONLY); - if (_gnutls_urandom_fd < 0) { - _gnutls_debug_log("Cannot open urandom!\n"); - return gnutls_assert_val(GNUTLS_E_RANDOM_DEVICE_ERROR); - } - - old = fcntl(_gnutls_urandom_fd, F_GETFD); - if (old != -1) - fcntl(_gnutls_urandom_fd, F_SETFD, old | FD_CLOEXEC); + /* Fallback: /dev/urandom */ - if (fstat(_gnutls_urandom_fd, &st) >= 0) { - _gnutls_urandom_fd_ino = st.st_ino; - _gnutls_urandom_fd_rdev = st.st_rdev; + /* Check that we can open it */ + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) { + _gnutls_debug_log("Cannot open /dev/urandom during initialization!\n"); + return gnutls_assert_val(GNUTLS_E_RANDOM_DEVICE_ERROR); } + close(urandom_fd); _rnd_get_system_entropy = _rnd_get_system_entropy_urandom; + _gnutls_debug_log("/dev/urandom random generator was selected\n"); return 0; } void _rnd_system_entropy_deinit(void) { - if (_gnutls_urandom_fd >= 0) { - close(_gnutls_urandom_fd); - _gnutls_urandom_fd = -1; - } + /* A no-op now when we open and close /dev/urandom every time */ + return; } diff --git a/lib/nettle/sysrng-netbsd.c b/lib/nettle/sysrng-netbsd.c index 7fb3d8d326..7f74b4eed4 100644 --- a/lib/nettle/sysrng-netbsd.c +++ b/lib/nettle/sysrng-netbsd.c @@ -71,11 +71,6 @@ int _rnd_system_entropy_init(void) return 0; } -int _rnd_system_entropy_check(void) -{ - return 0; -} - void _rnd_system_entropy_deinit(void) { return; diff --git a/lib/nettle/sysrng-windows.c b/lib/nettle/sysrng-windows.c index 9d38e67ec1..8c931d29cc 100644 --- a/lib/nettle/sysrng-windows.c +++ b/lib/nettle/sysrng-windows.c @@ -64,11 +64,6 @@ int _rnd_get_system_entropy_win32(void* rnd, size_t size) return 0; } -int _rnd_system_entropy_check(void) -{ - return 0; -} - int _rnd_system_entropy_init(void) { if (!CryptAcquireContext diff --git a/lib/random.h b/lib/random.h index 62b4dc2a07..0d76738971 100644 --- a/lib/random.h +++ b/lib/random.h @@ -33,9 +33,4 @@ extern gnutls_crypto_rnd_st _gnutls_rnd_ops; void _gnutls_rnd_deinit(void); int _gnutls_rnd_preinit(void); -inline static int _gnutls_rnd_check(void) -{ - return _rnd_system_entropy_check(); -} - #endif /* GNUTLS_LIB_RANDOM_H */ diff --git a/tests/rng-sigint.c b/tests/rng-sigint.c index 76b76f353c..04e818ede9 100644 --- a/tests/rng-sigint.c +++ b/tests/rng-sigint.c @@ -44,7 +44,6 @@ #define gnutls_assert_val(val) val int _rnd_system_entropy_init(void); -int _rnd_system_entropy_check(void); void _rnd_system_entropy_deinit(void); typedef int (*get_entropy_func)(void* rnd, size_t size); |