-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Description
Overview:
OpenSSL's configuration file can declare an acceleration engine, which usually looks like the following:
[openssl_def]
engines = engine_section
[engine_section]
ibmca = ibmca_section
[ibmca_section]
# The openssl engine path for ibmca.so.
# Set the dynamic_path to where the ibmca.so engine
# resides on the system.
dynamic_path = /usr/local/lib/ibmca.so
engine_id = ibmca
init = 1
The flow for loading such an engine is triggered by int_engine_configure, and when using a dynamic path it will dynamically load the engine's .so file using the engine's exported bind function. Once bound successfully, the engine is added by name (engine_id) to the engine list, which can only contain a single engine instance per such id.
As the engine list can only contain a single instance per engine_id, all engines that I've seen to date are built as singletons, which is an understandable implementation decision considering the engine API.
The Problem:
In the past there were multiple previous bugs of engines crashing after they get loaded twice:
- bind
- bind
- destroy
- Using the first engine <-- Many crashed happen here
- destroy <-- Some crashes happen here
One such cases is from 11 years ago and is reproduced when loading the engine twice.
Recent change in the initialization flow around OpenSSL 1.1.0/1.1.1 moved the invocation of CONF_modules_load_file() causing multiple projects to invoke it twice, thus triggering engine errors such as this one:
- wget - bugfix
- curl - bugfix
- Issue engine loaded twice, leading to name conflict #9481
- etc.
In fact, once Canonical and us debugged this case and found that both wget and curl crash due to loading the engine twice (PKA engine in our deployment), it led Canonical to start a package-wide search for other projects that might suffer from the same bug.
Suggestion:
While the different projects that use OpenSSL should fix their bug that cause them to load the configuration file twice, from the thread in #9481 it sounds like this shouldn't lead to segfaults in these programs, which is the case today. As loading an engine twice will always result in a failure to add it to the engine list, and the destruction of the just created engine, it seems like checking for the existence of an engine prior to creating / dynamically loading it, will resolve this repeating issue.
Again, it seems like errors / crashes caused by attempts to load an engine twice are a repeated issue around the OpenSSL API. I suggest to prevent the possibility of dynamically loading the engine if it was already loaded, and this will be a robust fix for this repeated issue.