charon-systemd: Don't use atexit() to deinitialize the daemon
authorTobias Brunner <tobias@strongswan.org>
Fri, 28 Sep 2018 17:55:52 +0000 (19:55 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 21 Nov 2018 13:31:49 +0000 (14:31 +0100)
commitcbe9e575eef5c3de165de05bf1d5ee2aaa5852e7
treef4337d2741629adb00ca58fa03ac30d643aecde9
parent2e49bbcc49930c6fa6317415555f89fe31c19ef2
charon-systemd: Don't use atexit() to deinitialize the daemon

This is because OpenSSL 1.1 started to use atexit()-handlers of its own
to clean up.  Since the plugin is loaded and initialized after libcharon,
OpenSSL's cleanup functions ran before the daemon was properly
deinitialized (i.e. worker threads were still running and OpenSSL might
still be used during the deinit).  So several of OpenSSL's internal
structures were already destroyed when libcharon_deinit() was eventually
called via our own atexit()-handler.

The observed behavior was that the daemon couldn't be terminated properly
anymore for some test scenarios (only three TNC scenarios were affected
actually).  When the daemon tried to send the DELETE for the established
IKE_SA during its termination it got stuck in OpenSSL's RNG_WEAK
implementation (used to allocate random padding), which apparently tries
to acquire an rwlock that was already destroyed.  The main thread then
just busy-waited indefinitely on the lock, i.e. until systemd killed
it eventually after a rather long timeout.

We'll probably have to apply similar changes to other apps/scripts that
load plugins and currently use atexit() to clean up.  Although some
scripts (e.g. dh_speed or hash_burn) are not affected because they
register the deinitialization after loading the plugins.
src/charon-systemd/charon-systemd.c