New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Keep /dev/random open for seeding #6432
Conversation
At present, there is no test and it isn't clear how an automated test could be written. A question that needs to be address is should the files be kept open for the entire list of DEVRANDOM seed sources or just one? This PR opts for the former, although they are initially opened as required rather than on startup. |
I think there should be a mechanism to ask for these files to be closed for an application that wants to do that - i.e. not have a leaking file descriptor ... |
That's fair enough. The chroot use case would suggest that keeping them open by default and having the option to close them is the way to go. This means introducing a new API to change the keep open behaviour. |
Or an API to provide for a cleanup separately - either way (change the open behaviour or allow for a specific cleanup call) there needs to be something new in place. And I don't think you have access to "conf" for handling that and I wouldn't suggest an environment variable to control it either. |
Added option to enable/disable the keep open semantics. Travis failures are unrelated. |
Which is the best lock to use to guard the set to close mode call? |
crypto/rand/rand_unix.c
Outdated
FILE *fp = devrandom_files[i]; | ||
|
||
if (fp == NULL) { | ||
if ((fp = fopen(devrandom_paths[i], "rb")) == NULL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is the _unix file, it might be useful to use open() instead of fopen() ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing code used fopen(3) and I stayed with that. I think @richsalz avoided open(2) deliberately. What do others think? I'm happy to change it.
There is also an issue with the reading code later -- if less than the full asked for amount is received, it is ignored. This is perplexing. Shouldn't whatever is read be used and accounted for? Unfortunately, the code is sufficiently complex to not be easily understandable. @mspncp any suggestion here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering we don't use any of the more advanced stdio functions, care about line endings and turn off buffering, I'd say that preferring FILE pointers over file descriptors is a moot point, and if using file descriptors gives us an advantage (such as fstat
mentioned elsewhere), it might as well be changed. One unnecessary layer removed...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for the bytes read being dropped unless it's all the bytes needed, I'm frankly not sure about that. Totally spaced on that last time I looked at this. That could surely be changed, no? Question is if it's something for this PR... (at the very least, it should be made a separate commit)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't whatever is read be used and accounted for?
I don't see any reason to discard the random data, just because it's less than the requested amount. Just grab anything you can get, add it to the pool, and drain the next source ;-).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use fileno() if you stay with FILE * and want to call fstat()
crypto/rand/rand_unix.c
Outdated
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(devrandom_paths); i++) { | ||
FILE *fp = devrandom_files[i]; | ||
|
||
if (fp == NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see a call to fstat(), and check S_ISCHR(), to see if the file is still open and still the type of file we expect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I'm happy to change this. Should we trust the configuration setting or should we check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I'm asking this is that I know that there is software that part as becoming a daemon will close all files. So they might have closed our file without us knowing about it, and it's very likely that something will reuse that file descriptor at a later point, say a network socket or log file. I want to avoid reading from an unexpected file. I guess we could cache the whole struct stat and check that some of the fields match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good enough reason for me. I'll add the check.
I prefer to only have 1 open file, instead of the 2 files you currently do. |
Does that mean only reading the seed from one source, or closing them directly after seeding except for the last one, which is kept open for reseeding? |
There will only be more than one open file if the first (or second -- the list is three long from memory) opens but doesn't deliver enough bytes. The first entry is set to There is also a concern with only opening one file at a time: if the read ever fails, the file is then closed and reopened which isn't possible in a chroot(2) environment. I'm happy to change things to only open one at a time or to open all up front but I'd like a consensus first. |
@levitte as I understand it, the current code will read from |
Since this is the case anyway, there is no need to have this complicated opening logic. I would just use the first handle that can be opened successfully. Since /dev/urandom preceeds /dev/random in the list, it does not really make sense to consider a situation where the first device fails but the second one succeeds. |
I'm hesitant to only keep one FD open. If, after the |
68fd6ce
to
8e89666
Compare
Updated to use FDs not FILE *. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be continued...
crypto/rand/rand_lib.c
Outdated
rand_pool_set_close_seed_files(close); | ||
} | ||
|
||
int RAND_get_close_seed_files(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a person who likes self describing function names in imperative style (CLASSNAME_do_this()
, CLASSNAME_enable_that()
), I would prefer to have a more descriptive function name than "this is the setter of some internal variable called close_seed_files
. Even more since
- There is no need for a setter/getter pair. This feature is under control of the application and nobody else should be changing it anyway. So there is no need for the application to query the current value.
- The term "seed files" is used nowhere else and is unnecessarily general; everywhere else we are talking about random device(s). Using such a general term just hides information to the programmer, which has no clue what precisely this function is doing unless he looks up the documentation or the source code.
My suggestion: Just drop the getter and rename the setter to something like
void RAND_keep_devrandom_open(int keep);
void RAND_keep_random_devices_open(int keep); /* <= my favorite choice */
or the other way around
void RAND_close_devrandom_after_use(int close);
void RAND_close_random_devices_after_use(int close);
edit: I forgot to commit a pendiing edit before sending off the review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I often admin I'm rubbish with API names :) I'll change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't use devrandom
in the names. Sure, this is currently very Unix centric, but should this become implemented on other platforms as well, devrandom
is as foreign a name as it gets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function exists solely to disable a workaround for a very unix-ish problem, namely that /dev/random might not be available after chroot(). So it is very unlikely that it will ever be used in a more general context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't use
devrandom
in the names.
Does this include random_devices
, too, or only devrandom
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
devrandom
specifically. random_devices
is fine in my mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to RAND_keep_random_devices_open
and removed the getter.
crypto/rand/rand_unix.c
Outdated
/* | ||
* Verify that the FD associated with the random source is an open character | ||
* device. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a suggestion:
/*
* Verify that the file descriptor associated with the random source is
* still valid and refers to a character device. The rationale for doing
* this is the fact that it is not uncommon for daemons to close all open
* file handles when daemonizing. So the handle might have been closed or
* even reused for opening another file.
*/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@EmericBr, would you mind checking whether nginx closes all open handles when chrooting? Because this would mean that this pull request would not work for your issue #5330 as expected (see my previous post).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See also #6432 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that would be a problem :(
Additionally and mostly as a reminder to myself, I need to check that Linux on the S390 uses character devices for its alternative random seed device nodes. I think other Unix based operating systems do, but I'll also check what I've got available too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternative I suggested was to cache the result of fstat() and then check that the st_dev, st_ino, st_mode and st_rdev fields are the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarification: this is not about an unnamed application. This is about haproxy.
Emeric is the maintainer of the SSL subsystem in haproxy, I myself am working on haproxy as well. I reproduced this first-hand in haproxy.
In the other thread I linked to the following haproxy troubleshooting session (where Sander, Emeric and myself confirmed the issue):
Haproxy 1.8 with OpenSSL 1.1.1-pre4 stops working after 1 hour
Sander runs an older kernel without getrandom functionality, Emeric cross-compiles without kernels headers (so the raw getrandom syscall doesn't work), and I had the kernel but not the libc, so it started working for me only with the raw getrandom syscall feature in -pre6.
I can see now that the nginx issue was not caused by chroot(), but by a permission problem (after nginx downgraded privileges). I'd argue that there's a possibility that keeping the FD open would have helped the nginx case as-well, depending on the initialization sequence - but let's focus on what we actually know. I apologize for the confusion my nginx comment caused.
Even more specifically, chroot(2) has to be called after rand is initialized.
Haproxy deliberately calls RAND_bytes() before chroot()ing to initialize OpenSSL's random number generator. Otherwise this would never have worked in the first place if I understand correctly.
As for the question of this being required or not or being post 1.1.1
In my opinion, if this doesn't hit 1.1.1, the entire discussion is quite useless, considering the breakage, the fact that 1.1.1 will be LTS and the post 1.1.1 release schedule ... unless you are willing to backport such a change to 1.1.1 post release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is about haproxy.
Cool! Thanks for clarification!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unless you are willing to backport such a change to 1.1.1 post release?
My argumentation in #6432 (comment) was to hold back the pull request as long as there is no concrete evidence of a regression yet, but of course keeping the option to backport it as bugfix to 1.1.1 if this would become necessary after the creation of the stable branch. Now since it has been clarified by you that haproxy is indeed affected by this regression, I would say it counts as bugfix and there is no need to hold back the pr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding this but with the default being not keeping the FD open?
Since haproxy is already making an effort to start the RAND system, would it be possible to modify it to support the new API to maintain the FDs open?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess making it not work by default in this instance isn't ideal.
5eb1641
to
75c0697
Compare
crypto/rand/rand_unix.c
Outdated
devrandom_files[n].mode = st.st_mode; | ||
devrandom_files[n].rdev = st.st_rdev; | ||
} else { | ||
devrandom_files[n].fd = -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formally speaking there is possibility for resource leak here. In case fd != -1 while return value from fstat(fd) is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I see why you were saying 'Formally speaking'. Looking at the error codes listed in stat(2) there really seems to be only a hypothetical chance that fstat() might fail in this situation. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ENOMEM would be possible. I'll fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter what is error condition or how impossible it is. Mere fact of checking the return value in given sequence formally makes it a possible resource leak.
doc/man3/RAND_add.pod
Outdated
@@ -54,6 +57,11 @@ should consider using L<RAND_load_file(3)> instead. | |||
|
|||
RAND_seed() is equivalent to RAND_add() with B<randomness> set to B<num>. | |||
|
|||
RAND_keep_random_devices_open() use used to control the resource use | |||
of the random device seed sources. Some seed sources maintain open file | |||
descriptors which allow them to operate in chroot(2) environment without |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"chroot(2) environment" is misleading, because "environment" gives an impression of something where you can start multiple processes. While the only thing that is effective in the context of proposed modification is operation within single process boundary that itself called chroot(2). Even more specifically, chroot(2) has to be called after rand is initialized.
I've made the requested changes. The default behaviour is still to keep the device FDs open. |
@paulidale, I have some suggestions for enhancements. For simplicity, I pushed them to my repository, separated in three commits, see suggestions-for-pr-6432. To briefly review the changes, visit mspncp#1, which extends your pull request. To get a local copy, do
Feel free to use (and squash) the suggestions if you like. |
doc/man3/RAND_add.pod
Outdated
@@ -54,6 +57,12 @@ should consider using L<RAND_load_file(3)> instead. | |||
|
|||
RAND_seed() is equivalent to RAND_add() with B<randomness> set to B<num>. | |||
|
|||
RAND_keep_random_devices_open() use used to control the resource use of | |||
the random device seed sources. Some seed sources are able to maintain | |||
open file descriptors which allow them to operate in chroot(2) jails |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd even go further saying current process's chroot jail.
As for not sending file descriptor. Basically rationale is following. It's only appropriate if API can be used in multiple situations. And problem is that suggested interface is usable only in one very particular scenario. While if you pass file descriptor it can used even in other scenarios. For example process that does chroot can pass file descriptor to children (by telling which one is it), which would make it possible to run chroot-ed children. They would naturally have to be modified to identify the file descriptor and pass it down to their copies of libcrypto... |
I meant the This at the end of CHANGES, line 12
Unfortunately I did not comment on the 'Files changed' page, but on the commit's page. That's why it came out so strange. |
But never mind, it's not important. |
211a85f
to
c8305f9
Compare
This is on a new line now. |
Approvals needed from @levitte and @mattcaswell |
(I'm happy with the doc changes, leaving approval of the rest to others) |
doc/man3/RAND_add.pod
Outdated
by default, which allows such sources to operate in a chroot(2) jail | ||
without the associated device nodes being available. When the B<keep> argument | ||
is zero, this call disables the retention of file descriptors. Conversely, | ||
a non-zero argument enables the retention of file descriptors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it this only has an effect the next time we get more entropy from the seed sources, i.e. calling RAND_keep_random_devices_open(0), would not immediately close already open file descriptors. Should we say something about that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RAND_keep_random_devices_open(0), would not immediately close already open file descriptors.
False, the file descriptors are closed immediately in rand_pool_keep_random_devices_open().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - right! My misunderstanding. In that case, do we need to say that this happens immediately?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The normal use case would be to call RAND_keep_random_devices_open()
only once during initialization before the first randomness is generated (in which case it makes no difference how it's implemented). You normally don't flip this feature on and off. So maybe better add a sentence that this should be called during early initialization (unless one is happy with the default).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a sentence and rebased to avoid merge conflicts.
1a651c8
to
df79de7
Compare
the B<keep> argument is zero, this call disables the retention of file | ||
descriptors. Conversely, a non-zero argument enables the retention of | ||
file descriptors. This function is usually called during initialization | ||
and it takes effect immediately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry for not asking earlier: shouldn't we also mention that this feature is enabled by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Earlier in the paragraph: Some seed sources maintain open file
descriptors by default, ... Isn't that enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, I forgot about that. The early bird is not quite awake yet. Thanks for the reminder!
@mattcaswell your approval is the missing piece at the moment :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved assuming the typo is fixed.
@@ -54,6 +57,15 @@ should consider using L<RAND_load_file(3)> instead. | |||
|
|||
RAND_seed() is equivalent to RAND_add() with B<randomness> set to B<num>. | |||
|
|||
RAND_keep_random_devices_open() is used to control file descriptor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
descriptors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's "file descriptor use", but maybe @paulidale should break the line after "use", otherwise more readers will stumble over it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or "file descriptor usage"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh..right. My mistake. Actually the line break is probably not that big a deal because it won't necessarily be there when this gets rendered as a man page.
…tly. This allows operation inside a chroot environment without having the random device present. A new call, RAND_keep_random_devices_open(), has been introduced that can be used to control file descriptor use by the random seed sources. Some seed sources maintain open file descriptors by default, which allows such sources to operate in a chroot(2) jail without the associated device nodes being available.
df79de7
to
04df958
Compare
Thanks to all, the final documentation change has been made and everything is merged. |
…tly. This allows operation inside a chroot environment without having the random device present. A new call, RAND_keep_random_devices_open(), has been introduced that can be used to control file descriptor use by the random seed sources. Some seed sources maintain open file descriptors by default, which allows such sources to operate in a chroot(2) jail without the associated device nodes being available. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> (Merged from #6432)
I really didn't have time to look at this. It seems that
that /dev/urandom and /dev/random are now always opened by default
even if it's never read. I guess I would prefer to only open them
when no system call is available, but I can live with the current
situation.
|
I'd be a little uncomfortable about introducing this kind of dependencies between the seed sources. It complicates the code and simpler is better here. If desirable, I can raise an issue for future consideration -- either add the exception to the code or document the behaviour and suggesting not enabling this source if it is a concern. |
Fixes openssl#7022 In pull request openssl#6432 a change was made to keep the handles to the random devices opened in order to avoid reseeding problems for applications in chroot environments. As a consequence, the handles of the random devices were leaked at exit if the random generator was not used by the application. This happened, because the call to RAND_set_rand_method(NULL) in rand_cleanup_int() triggered a call to the call_once function do_rand_init, which opened the random devices via rand_pool_init(void). Thanks to GitHub user @bwelling for reporting this issue.
Fixes #7022 In pull request #6432 a change was made to keep the handles to the random devices opened in order to avoid reseeding problems for applications in chroot environments. As a consequence, the handles of the random devices were leaked at exit if the random generator was not used by the application. This happened, because the call to RAND_set_rand_method(NULL) in rand_cleanup_int() triggered a call to the call_once function do_rand_init, which opened the random devices via rand_pool_init(). Thanks to GitHub user @bwelling for reporting this issue. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from #7023)
Commit c7504ae (pr openssl#6432) fixed a regression for applications in chroot environments, which compensated the fact that the new OpenSSL CSPRNG (based on the NIST DRBG) now reseeds periodically, which the previous one didn't. Now the reseeding could fail in the chroot environment if the DEVRANDOM devices were not present anymore and no other entropy source (e.g. getrandom()) was available. The solution was to keep the file handles for the DEVRANDOM devices open by default. In fact, the fix did more than this, it opened the DEVRANDOM devices early and unconditionally in rand_pool_init(), which had the unwanted side effect that the devices were opened (and kept open) even in cases when they were not used at all, for example when the getrandom() system call was available. Due to a bug (issue openssl#7419) this even happened when the feature was disabled by the application. This commit removes the unconditional opening of all DEVRANDOM devices. They will now only be opened (and kept open) on first use. In particular, if getrandom() is available, the handles will not be opened unnecessarily. This change does not introduce a regression for applications compiled for libcrypto 1.1.0, because the SSLEAY RNG also seeds on first use. So in the above constellation the CSPRNG will only be properly seeded if it is happens before the forking and chrooting. Fixes openssl#7419
Commit c7504ae (pr #6432) fixed a regression for applications in chroot environments, which compensated the fact that the new OpenSSL CSPRNG (based on the NIST DRBG) now reseeds periodically, which the previous one didn't. Now the reseeding could fail in the chroot environment if the DEVRANDOM devices were not present anymore and no other entropy source (e.g. getrandom()) was available. The solution was to keep the file handles for the DEVRANDOM devices open by default. In fact, the fix did more than this, it opened the DEVRANDOM devices early and unconditionally in rand_pool_init(), which had the unwanted side effect that the devices were opened (and kept open) even in cases when they were not used at all, for example when the getrandom() system call was available. Due to a bug (issue #7419) this even happened when the feature was disabled by the application. This commit removes the unconditional opening of all DEVRANDOM devices. They will now only be opened (and kept open) on first use. In particular, if getrandom() is available, the handles will not be opened unnecessarily. This change does not introduce a regression for applications compiled for libcrypto 1.1.0, because the SSLEAY RNG also seeds on first use. So in the above constellation the CSPRNG will only be properly seeded if it is happens before the forking and chrooting. Fixes #7419 Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from #7437)
Commit c7504ae (pr #6432) fixed a regression for applications in chroot environments, which compensated the fact that the new OpenSSL CSPRNG (based on the NIST DRBG) now reseeds periodically, which the previous one didn't. Now the reseeding could fail in the chroot environment if the DEVRANDOM devices were not present anymore and no other entropy source (e.g. getrandom()) was available. The solution was to keep the file handles for the DEVRANDOM devices open by default. In fact, the fix did more than this, it opened the DEVRANDOM devices early and unconditionally in rand_pool_init(), which had the unwanted side effect that the devices were opened (and kept open) even in cases when they were not used at all, for example when the getrandom() system call was available. Due to a bug (issue #7419) this even happened when the feature was disabled by the application. This commit removes the unconditional opening of all DEVRANDOM devices. They will now only be opened (and kept open) on first use. In particular, if getrandom() is available, the handles will not be opened unnecessarily. This change does not introduce a regression for applications compiled for libcrypto 1.1.0, because the SSLEAY RNG also seeds on first use. So in the above constellation the CSPRNG will only be properly seeded if it is happens before the forking and chrooting. Fixes #7419 Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from #7437) (cherry picked from commit 8cfc197)
Modify the DEVRANDOM seed source so that the files are kept open persistently.
This allows operation inside a chroot environment without having the random
device present.
Following from #5330