From: merch-redmine@... Date: 2021-03-10T17:27:46+00:00 Subject: [ruby-core:102809] [Ruby master Bug#14716] SecureRandom throwing an error in Ruby 2.5.1 Issue #14716 has been updated by jeremyevans0 (Jeremy Evans). xtkoba (Tee KOBAYASHI) wrote in #note-19: > To my understanding, the problem is that when `Random.urandom` failed to use `/dev/urandom` it does not fall back to using an OpenSSL function even if it is available. Ah, thank you, that is an important insight I missed. However, I think such a fallback is problematic, for two reasons: 1) If openssl has not been required yet, it would have to require openssl, which would require a file descriptor, and we are already out of file descriptors. 2) Even if openssl has already been required, it needs to seed the OpenSSL random generator using `/dev/urandom`, which would also require a file descriptor (see get_random_openssl). The only way for this to work would be to have securerandom always require openssl and either preseed the OpenSSL random generator (which would still fail in forked processes) or directly call `OpenSSL::Random.random_bytes` without seeding the OpenSSL random generator, which sounds like a bad idea from a security perspective. I also think it's undesirable for securerandom to require openssl just to use it for fallback. In my opinion, if you are using an operating system that uses on `/dev/urandom` for random data and want randomness to be immune to file descriptor exhaustion, you should use `OpenSSL::Random.random_bytes` directly. If we did want a fallback, something like this could work: ```diff diff --git a/lib/securerandom.rb b/lib/securerandom.rb index 241fde98ce..034f60b468 100644 --- a/lib/securerandom.rb +++ b/lib/securerandom.rb @@ -89,7 +89,14 @@ def gen_random_openssl(n) end def gen_random_urandom(n) - ret = Random.urandom(n) + begin + ret = Random.urandom(n) + rescue RuntimeError + if defined?(OpenSSL::Random) + ret = OpenSSL::Random.random_bytes(n) + end + end + unless ret raise NotImplementedError, "No random device" end @@ -109,6 +116,12 @@ def gen_random_urandom(n) alias gen_random gen_random_openssl end else + begin + require 'openssl' + rescue + else + SecureRandom.send(:gen_random_openssl, 1) + end alias gen_random gen_random_urandom end ``` However, as I mentioned, I think this is a bad idea. ---------------------------------------- Bug #14716: SecureRandom throwing an error in Ruby 2.5.1 https://bugs.ruby-lang.org/issues/14716#change-90830 * Author: snehavas (sneha vasanth) * Status: Feedback * Priority: Normal * ruby -v: 2.6.3 * Backport: 2.3: DONTNEED, 2.4: DONTNEED, 2.5: REQUIRED ---------------------------------------- Hi, We recently upgraded from ruby 2.3.6 to 2.5.1. We use SecureRandom.uuid to generate a random number for our session. Post the upgrade we have been getting the following error intermittently ``` app error: failed to get urandom (RuntimeError) E, [2018-04-27T04:55:08.741859 #16550] ERROR -- : /usr/lib/ruby/2.5.0/securerandom.rb:99:in `urandom' E, [2018-04-27T04:55:08.741898 #16550] ERROR -- : /usr/lib/ruby/2.5.0/securerandom.rb:99:in `gen_random_urandom' E, [2018-04-27T04:55:08.741932 #16550] ERROR -- : /usr/lib/ruby/2.5.0/securerandom.rb:129:in `random_bytes' E, [2018-04-27T04:55:08.741965 #16550] ERROR -- : /usr/lib/ruby/2.5.0/securerandom.rb:219:in `uuid' E, [2018-04-27T04:55:08.741997 #16550] ERROR -- : /usr/share/nginx/frontend/app/utilities/log.rb:74:in `create_session_info' E, [2018-04-27T04:55:08.742036 #16550] ERROR -- : /usr/share/nginx/frontend/app/utilities/log.rb:11:in `context' ``` We understand that there was a change in ruby 2.5.1 where we now look at OS sources as the first point of contact to generate random numbers as opposed to OpenSSL. Any idea why this could be happening? -- https://bugs.ruby-lang.org/ Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>