-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Description
Using OpenSSL 1.1.1 in Arch linux, when checking lsof on a long-running application I noticed that /dev/random/ and /dev/urandom were being opened by something. Some digging around found that a relatively recent OpenSSL change was to blame and that using RAND_keep_random_devices_open(0); would stop that behavior (This program execs itself to refresh its binary without dropping established connections, so leaving them open was causing a descriptor leak). The man page says it takes effect immediately and should be called during initialization, but I found that it working is very dependent on when in the program the function is called -- use it before any other OpenSSL routines that use random numbers, and the descriptors will be left open.
Consider this demonstration program:
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <unistd.h>
#include <stdlib.h>
int main(void) {
BIGNUM *bn;
BN_CTX *ctx;
RAND_keep_random_devices_open(0);
ctx = BN_CTX_new();
bn = BN_new();
BN_set_word(bn, 1567);
BN_is_prime_ex(bn, BN_prime_checks, ctx, NULL);
sleep(10);
return 0;
}
and the relevant strace output:
openat(AT_FDCWD, "/dev/urandom", O_RDONLY) = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0
openat(AT_FDCWD, "/dev/random", O_RDONLY) = 4
fstat(4, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 8), ...}) = 0
openat(AT_FDCWD, "/dev/srandom", O_RDONLY) = -1 ENOENT (No such file or directory)
futex(0x7f7ebc7db948, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f7ebc7db7f8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f7ebc7db7ec, FUTEX_WAKE_PRIVATE, 2147483647) = 0
getrandom("\x5b\xcd\xab\xc5\xa8\x3c\x89\x84\x8f\xcd\x97\x85\x90\x1a\x00\x22\xb3\x42\x4d\x53\x6b\xa6\xef\xa6\xad\x5e\xb2\x83\x2d\x99\x67\x8d", 32, 0) = 32
getpid() = 21486
clock_gettime(CLOCK_REALTIME, {tv_sec=1539757629, tv_nsec=856678890}) = 0
futex(0x7f7ebc7db918, FUTEX_WAKE_PRIVATE, 2147483647) = 0
nanosleep({tv_sec=10, tv_nsec=0}, 0x7ffea2d3c070) = 0
futex(0x7f7ebc7db6a4, FUTEX_WAKE_PRIVATE, 2147483647) = 0
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0
close(3) = 0
fstat(4, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 8), ...}) = 0
close(4) = 0
exit_group(0) = ?
+++ exited with 0 +++
It only closes the descriptors (3 and 4) when the program exits normally. If it instead execs another program, they're left open and unused in it. If I move the RAND_keep_random_devices_open() call to just below the sleep(), they get closed right then, though. Instead of having to figure out by trial and error where to call the function, it'd be nice if it behaved as advertised. (I'm also not sure why it's opening the random device files at all when it uses the getrandom() syscall instead to seed things, or why it's opening both more than one...)