Skip to content

Commit

Permalink
Ensure that libcrypto and libssl do not unload until the process exits
Browse files Browse the repository at this point in the history
Because we use atexit() to cleanup after ourselves, this will cause a
problem if we have been dynamically loaded and then unloaded again: the
atexit() handler may no longer be there.

Most modern atexit() implementations can handle this, however there are
still difficulties if libssl gets unloaded before libcrypto, because of
the atexit() callback that libcrypto makes to libssl.

The most robust solution seems to be to ensure that libcrypto and libssl
never unload. This is done by simply deliberately leaking a dlopen()
reference to them.

Reviewed-by: Tim Hudson <tjh@openssl.org>
(cherry picked from commit 5836780)
  • Loading branch information
mattcaswell committed Nov 2, 2016
1 parent f722f18 commit 4af9f7f
Showing 1 changed file with 31 additions and 0 deletions.
31 changes: 31 additions & 0 deletions crypto/init.c
Expand Up @@ -23,6 +23,7 @@
#include <stdlib.h>
#include <assert.h>
#include <internal/thread_once.h>
#include <internal/dso.h>

static int stopped = 0;

Expand Down Expand Up @@ -79,6 +80,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base)
return 0;
OPENSSL_cpuid_setup();
base_inited = 1;

/*
* Deliberately leak a reference to ourselves. This will force the library
* to remain loaded until the atexit() handler is run a process exit.
*/
{
DSO *dso = NULL;

dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
DSO_free(dso);
}

return 1;
}

Expand Down Expand Up @@ -575,6 +588,24 @@ int OPENSSL_atexit(void (*handler)(void))
{
OPENSSL_INIT_STOP *newhand;

/*
* Deliberately leak a reference to the handler. This will force the
* library/code containing the handler to remain loaded until we run the
* atexit handler.
*/
{
DSO *dso = NULL;
union {
void *sym;
void (*func)(void);
} handlersym;

handlersym.func = handler;

dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
DSO_free(dso);
}

newhand = OPENSSL_malloc(sizeof(*newhand));
if (newhand == NULL)
return 0;
Expand Down

0 comments on commit 4af9f7f

Please sign in to comment.