summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2021-03-11 06:23:03 +0000
committerDaiki Ueno <ueno@gnu.org>2021-03-11 06:23:03 +0000
commitc95312c5831be5418dc02a86d72bcd1eafd4c145 (patch)
treed6ef20b98fb962644ed056114f5f22ca5c03d795
parent776eeadf468318c4ceb80abe96a8017ab4ae0bc0 (diff)
parentdb5e38aec5123b6fa4ad5eed7961adbd83deecba (diff)
downloadgnutls-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.c10
-rw-r--r--lib/nettle/rnd-common.h1
-rw-r--r--lib/nettle/sysrng-bcrypt.c5
-rw-r--r--lib/nettle/sysrng-getentropy.c5
-rw-r--r--lib/nettle/sysrng-linux.c68
-rw-r--r--lib/nettle/sysrng-netbsd.c5
-rw-r--r--lib/nettle/sysrng-windows.c5
-rw-r--r--lib/random.h5
-rw-r--r--tests/rng-sigint.c1
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);