-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Enable compact index when OpenSSL FIPS mode is enabled but not active #5440
Enable compact index when OpenSSL FIPS mode is enabled but not active #5440
Conversation
How does this behave on Windows environments? Specifically when you're writing to |
f015d4d
to
fa448c7
Compare
I believe that |
lib/bundler/fetcher/compact_index.rb
Outdated
@@ -122,14 +122,24 @@ def call(path, headers) | |||
end | |||
|
|||
def md5_available? | |||
return true unless fips_enabled? && Process.respond_to?(:fork) | |||
pid = fork do |
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 don't think forking on every Bundler process is going to be acceptable performance-wise (in addition to all the platforms that aren't fork-safe) -- is there no way to determine in-process if the MD5 digest is available?
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.
- Platforms that aren't fork-safe will not reach this line of code because
Process.respond_to?(:fork)
will befalse
. - Performance-wise, I expect a process fork to perform better than disabling the compact-index entirely, so for the case where FIPS mode is available but not active this should be a performance improvement. The tradeoff is that this causes the case where FIPS mode is active to perform the fork.
- As far as I can tell, there is no way via Ruby's stdlib to determine in-process if the MD5 digest is available. The process is aborted as soon as OpenSSH's MD5 module is invoked, so in order to detect this failure without aborting the parent process, it's necessary to perform the test on a child process.
fa448c7
to
873bac1
Compare
The solution to #5222 is the best we have currently, some users were unable to use Bundler when FIPS was enabled so loosing Compact Index is a suitable compromise. I'll ask the OpenSSL gem maintainers if we can work to improve the API to better detect FIPS. |
Looking at the OpenSSL gem src there is a method called |
@colby-swandale it was introduced in Ruby 2.0 and it is just setter ( You can check if fips mode is enabled by this code: require 'openssl'
require 'fiddle'
puts Fiddle::Function.new(Fiddle.dlopen(nil)["FIPS_mode"], [], Fiddle::TYPE_INT).call() I can try to open PR to Ruby OpenSSL to add this as |
Alternatively OpenSSL::Digest which uses the EVP interface can be used. def md5_available?
return true unless defined?(OpenSSL)
OpenSSL::Digest::MD5.digest("")
true
rescue OpenSSL::Digest::DigestError
false
end |
# OpenSSL writes to STDERR and kills the current process with SIGABRT | ||
# when FIPS mode prevents MD5 from being used. | ||
$stderr.write "Digest MD5 forbidden in FIPS mode!" | ||
Process.kill("ABRT", Process.pid) |
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.
Is this still necessary?
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.
No, this is not necessary anymore for the spec to run correctly, I can remove.
Looks good to me! |
This is awesome teamwork, everyone. Thanks so much! @bundlerbot r+ |
📌 Commit 21b3358 has been approved by |
Enable compact index when OpenSSL FIPS mode is enabled but not active Fixes #5433. Since there is no easy accessor in Ruby to detect whether or not FIPS mode is currently active, the best approach I could come up with is to `fork` a separate process and attempt to generate a build MD5 object as a test of whether MD5 module is currently available. Because `fork` approach won't work on some platforms (JRuby, Windows etc), `md5_supported?` returns `false` on any platforms where FIPS mode is enabled and `Process.respond_to?(:fork)` is `false`. I've added a spec that simulates behavior when OpenSSL FIPS mode is active - an error message is output to STDERR and the process is killed with the `ABRT` signal.
☀️ Test successful - status-travis |
Enable compact index when OpenSSL FIPS mode is enabled but not active Fixes #5433. Since there is no easy accessor in Ruby to detect whether or not FIPS mode is currently active, the best approach I could come up with is to `fork` a separate process and attempt to generate a build MD5 object as a test of whether MD5 module is currently available. Because `fork` approach won't work on some platforms (JRuby, Windows etc), `md5_supported?` returns `false` on any platforms where FIPS mode is enabled and `Process.respond_to?(:fork)` is `false`. I've added a spec that simulates behavior when OpenSSL FIPS mode is active - an error message is output to STDERR and the process is killed with the `ABRT` signal. (cherry picked from commit 13f4cc1)
Fixes #5433. Since there is no easy accessor in Ruby to detect whether or not FIPS mode is currently active, the best approach I could come up with is to
fork
a separate process and attempt to generate a build MD5 object as a test of whether MD5 module is currently available.Because
fork
approach won't work on some platforms (JRuby, Windows etc),md5_supported?
returnsfalse
on any platforms where FIPS mode is enabled andProcess.respond_to?(:fork)
isfalse
.I've added a spec that simulates behavior when OpenSSL FIPS mode is active - an error message is output to STDERR and the process is killed with the
ABRT
signal.