Explicit thread cleanup in OpenSSL 1.1.1 possible?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Explicit thread cleanup in OpenSSL 1.1.1 possible?

Stephan Mühlstrasser
Hi,

with OpenSSL 1.1.1 it is possible to turn off the automatic cleanup with
an atexit() handler by passing the flag OPENSSL_INIT_NO_ATEXIT to
OPENSSL_init_crypto().

Is it possible to configure this also at the thread level, so that no
automatic thread cleanup occurs, with the option to do an explicit
per-thread cleanup? I looked at documentation and source code of OpenSSL
1.1.1 and this seems not to be possible, but I wanted to ask nevertheless.

Background: We are embedding OpenSSL in a Java JNI library, and one
particular JVM (IBM J9 on z/OS) loads our Java class and the JNI library
in a dedicated thread. At the end of the program the JVM then unloads
the the Java class and the JNI library before the thread terminates, and
when the OpenSSL thread cleanup functions are called the JVM crashes
because the shared library is gone from the address space. This happens
because the pinning of the OpenSSL shared library does not work on z/OS.

--
Stephan
Reply | Threaded
Open this post in threaded view
|

Re: Explicit thread cleanup in OpenSSL 1.1.1 possible?

Michael Wojcik
As a workaround, what about first making a JNI call to a trivial shared object that does an explicit dlopen of the OpenSSL shared object? The JVM wouldn't know about that load, and its subsequent unload of the shared object wouldn't remove it from the process address space, because there would still be a reference to it.
Reply | Threaded
Open this post in threaded view
|

Re: Explicit thread cleanup in OpenSSL 1.1.1 possible?

Stephan Mühlstrasser
Hello Michael,

Am 27.03.20 um 15:46 schrieb Michael Wojcik:
> As a workaround, what about first making a JNI call to a trivial shared
> object that does an explicit dlopen of the OpenSSL shared object? The
> JVM wouldn't know about that load, and its subsequent unload of the
> shared object wouldn't remove it from the process address space, because
> there would still be a reference to it.

thanks for the suggestion. This sounds similar to the trick that is
already built into OpenSSL.

Through other channels I found now two other possible solutions for the
problem:

1) Use JNI_OnUnload() to call OPENSSL_cleanup()

JNI_OnUnload() is called when the JVM unloads the JNI library.
OPENSSL_cleanup() cleans up everything and no further per-thread cleanup
happens after unloading the JNI shared library.

2) Use a C++ static object in the JNI library where the destructor calls
OPENSSL_cleanup()

When debugging the problem I came across this neat trick on stackoverflow:

https://stackoverflow.com/a/11394263

class ResourceHolder {
public:
     ResourceHolder() {
         // at start
     }

     ~ResourceHolder() {
         // at exit
     }
};

ResourceHolder theHolder;

I think that putting a call to OPENSSL_cleanup() into the destructor of
the ResourceHolder class would also fix the problem, and it would be
Java-agnostic.

Approach 1) does fix the crash for me. If approach 2) works as well, I
will use that one.

--
Stephan