Openssl static build linked in DLL does not unload on win32

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Openssl static build linked in DLL does not unload on win32

Dan Heinz

Using openssl 1.1.0c. 

I have a test application that is a win32 console app that calls a win32 DLL which has the openssl libraries linked in statically.

The test applications uses late-binding to the DLL and calls LoadLibrary for the DLL, one test function in the DLL, and then FreeLibrary on the DLL.

 

The test function in the DLL does the following:

RSA *rsa = NULL;

rsa = RSA_new();

RSA_free(rsa);

OPENSSL_thread_stop();

OPENSSL_cleanup();

return 0;

 

When FreeLibrary is called on the DLL, dllmain in never called with any messages.  A subsequent call to LoadLibrary also fails to call dllmain and when the test function is called RSA_new() fails.  This leads me to believe the DLL is never freed.

 

I have tried building openssl with and without no-threads with the same results.  My build parameters are:
perl Configure %TEMP_ARCHITECTURE% --prefix=%RootPath_ThirdParty%\%OPENSSL_VERSION% -DPURIFY -DOPENSSL_NO_COMP -D_USING_V110_SDK71_ no-shared no-threads no-asm  no-idea no-mdc2 no-rc5  no-ssl3 no-zlib no-comp

 

What am I missing?

 


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Matt Caswell-2


On 04/01/17 23:11, Dan Heinz wrote:

> Using openssl 1.1.0c.
>
> I have a test application that is a win32 console app that calls a win32
> DLL which has the openssl libraries linked in statically.
>
> The test applications uses late-binding to the DLL and calls LoadLibrary
> for the DLL, one test function in the DLL, and then FreeLibrary on the DLL.
>
>  
>
> The test function in the DLL does the following:
>
> RSA*rsa = NULL;
>
> rsa = RSA_new();
>
> RSA_free(rsa);
>
> OPENSSL_thread_stop();
>
> OPENSSL_cleanup();
>
> return0;
>
> When FreeLibrary is called on the DLL, dllmain in never called with any
> messages.  A subsequent call to LoadLibrary also fails to call dllmain
> and when the test function is called RSA_new() fails.  This leads me to
> believe the DLL is never freed.
>
> I have tried building openssl with and without no-threads with the same
> results.  My build parameters are:
> perl Configure *%TEMP_ARCHITECTURE%*
> --prefix=*%RootPath_ThirdParty%*\*%OPENSSL_VERSION%* -DPURIFY
> -DOPENSSL_NO_COMP -D_USING_V110_SDK71_ no-shared no-threads no-asm
> no-idea no-mdc2 no-rc5  no-ssl3 no-zlib no-comp
>
> What am I missing?


OpenSSL does its cleanup at *process* exit. Don't call OPENSSL_cleanup()
explicitly - this is discouraged.

From this manpage:

https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html

"Typically there should be no need to call this function directly as it
is initiated automatically on application exit...<snip>...

Once OPENSSL_cleanup() has been called the library cannot be reinitialised."

This last sentence is the reason why RSA_new() will fail after you have
previously called OPENSSL_cleanup().

Because cleanup happens on process exit, OpenSSL will keep itself in
memory until that time (otherwise crashes will occur because the cleanup
routines have been unloaded).

If you want to dynamically load and unload your DLL then don't
statically link it to OpenSSL - otherwise OpenSSL will keep your DLL
around until process exit too.

Matt
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Jakob Bohm-7
On 05/01/2017 11:53, Matt Caswell wrote:

> On 04/01/17 23:11, Dan Heinz wrote:
>> Using openssl 1.1.0c.
>>
>> I have a test application that is a win32 console app that calls a win32
>> DLL which has the openssl libraries linked in statically.
>>
>> The test applications uses late-binding to the DLL and calls LoadLibrary
>> for the DLL, one test function in the DLL, and then FreeLibrary on the DLL.
>>
>>  
>>
>> The test function in the DLL does the following:
>>
>> RSA*rsa = NULL;
>>
>> rsa = RSA_new();
>>
>> RSA_free(rsa);
>>
>> OPENSSL_thread_stop();
>>
>> OPENSSL_cleanup();
>>
>> return0;
>>
>> When FreeLibrary is called on the DLL, dllmain in never called with any
>> messages.  A subsequent call to LoadLibrary also fails to call dllmain
>> and when the test function is called RSA_new() fails.  This leads me to
>> believe the DLL is never freed.
>>
>> I have tried building openssl with and without no-threads with the same
>> results.  My build parameters are:
>> perl Configure *%TEMP_ARCHITECTURE%*
>> --prefix=*%RootPath_ThirdParty%*\*%OPENSSL_VERSION%* -DPURIFY
>> -DOPENSSL_NO_COMP -D_USING_V110_SDK71_ no-shared no-threads no-asm
>> no-idea no-mdc2 no-rc5  no-ssl3 no-zlib no-comp
>>
>> What am I missing?
> OpenSSL does its cleanup at *process* exit. Don't call OPENSSL_cleanup()
> explicitly - this is discouraged.
>
>  From this manpage:
>
> https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html
>
> "Typically there should be no need to call this function directly as it
> is initiated automatically on application exit...<snip>...
>
> Once OPENSSL_cleanup() has been called the library cannot be reinitialised."
>
> This last sentence is the reason why RSA_new() will fail after you have
> previously called OPENSSL_cleanup().
>
> Because cleanup happens on process exit, OpenSSL will keep itself in
> memory until that time (otherwise crashes will occur because the cleanup
> routines have been unloaded).
>
> If you want to dynamically load and unload your DLL then don't
> statically link it to OpenSSL - otherwise OpenSSL will keep your DLL
> around until process exit too.
>
> Matt
Which is a horribly broken design by the OpenSSL team, especially if
the surrounding process is extremely long-running.  Otherwise, security
updates to OpenSSL will end up requiring system reboots to ensure that
all OpenSSL-using code actually runs the updated OpenSSL libraries.

Someone needs to go back to the drawing board and make OpenSSL
unloadable again.

Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Dan Heinz
In reply to this post by Matt Caswell-2
>>On 04/01/17 23:11, Dan Heinz wrote:
>> Using openssl 1.1.0c.
>>
>> I have a test application that is a win32 console app that calls a
>> win32 DLL which has the openssl libraries linked in statically.
>>
>> The test applications uses late-binding to the DLL and calls
>> LoadLibrary for the DLL, one test function in the DLL, and then FreeLibrary on the DLL.
>>
>>  
>>
>> The test function in the DLL does the following:
>>
>> RSA*rsa = NULL;
>>
>> rsa = RSA_new();
>>
>> RSA_free(rsa);
>>
>> OPENSSL_thread_stop();
>>
>> OPENSSL_cleanup();
>>
>> return0;
>>
>> When FreeLibrary is called on the DLL, dllmain in never called with
>> any messages.  A subsequent call to LoadLibrary also fails to call
>> dllmain and when the test function is called RSA_new() fails.  This
>> leads me to believe the DLL is never freed.
>>
>> I have tried building openssl with and without no-threads with the
>> same results.  My build parameters are:
>> perl Configure *%TEMP_ARCHITECTURE%*
>> --prefix=*%RootPath_ThirdParty%*\*%OPENSSL_VERSION%* -DPURIFY
>> -DOPENSSL_NO_COMP -D_USING_V110_SDK71_ no-shared no-threads no-asm
>> no-idea no-mdc2 no-rc5  no-ssl3 no-zlib no-comp
>>
>> What am I missing?
>
>
>OpenSSL does its cleanup at *process* exit. Don't call OPENSSL_cleanup() explicitly - this is >discouraged.
>
>From this manpage:
>
>https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html
>
>"Typically there should be no need to call this function directly as it is initiated >automatically on application exit...<snip>...
>
>Once OPENSSL_cleanup() has been called the library cannot be reinitialised."
>
>This last sentence is the reason why RSA_new() will fail after you have previously called >OPENSSL_cleanup().
>
>Because cleanup happens on process exit, OpenSSL will keep itself in memory until that time >(otherwise crashes will occur because the cleanup routines have been unloaded).
>
>If you want to dynamically load and unload your DLL then don't statically link it to OpenSSL - >otherwise OpenSSL will keep your DLL around until process exit too.
>
>Matt

That is very disappointing.  As a library vendor we have no control over how our users load and unload our libraries.  We will just have to roll back to 1.0.x and wait to see if this will be addressed.  
Also, as Jakob stated in another post, it really seems like this design will be problematic.  

Thanks,
Dan
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Matt Caswell-2


On 06/01/17 14:36, Dan Heinz wrote:

>>> On 04/01/17 23:11, Dan Heinz wrote: Using openssl 1.1.0c.
>>>
>>> I have a test application that is a win32 console app that calls
>>> a win32 DLL which has the openssl libraries linked in
>>> statically.
>>>
>>> The test applications uses late-binding to the DLL and calls
>>> LoadLibrary for the DLL, one test function in the DLL, and then
>>> FreeLibrary on the DLL.
>>>
>>>
>>>
>>> The test function in the DLL does the following:
>>>
>>> RSA*rsa = NULL;
>>>
>>> rsa = RSA_new();
>>>
>>> RSA_free(rsa);
>>>
>>> OPENSSL_thread_stop();
>>>
>>> OPENSSL_cleanup();
>>>
>>> return0;
>>>
>>> When FreeLibrary is called on the DLL, dllmain in never called
>>> with any messages.  A subsequent call to LoadLibrary also fails
>>> to call dllmain and when the test function is called RSA_new()
>>> fails.  This leads me to believe the DLL is never freed.
>>>
>>> I have tried building openssl with and without no-threads with
>>> the same results.  My build parameters are: perl Configure
>>> *%TEMP_ARCHITECTURE%*
>>> --prefix=*%RootPath_ThirdParty%*\*%OPENSSL_VERSION%* -DPURIFY
>>> -DOPENSSL_NO_COMP -D_USING_V110_SDK71_ no-shared no-threads
>>> no-asm no-idea no-mdc2 no-rc5  no-ssl3 no-zlib no-comp
>>>
>>> What am I missing?
>>
>>
>> OpenSSL does its cleanup at *process* exit. Don't call
>> OPENSSL_cleanup() explicitly - this is >discouraged.
>>
>> From this manpage:
>>
>> https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html
>>
>>
>>
"Typically there should be no need to call this function directly as it
is initiated >automatically on application exit...<snip>...

>>
>> Once OPENSSL_cleanup() has been called the library cannot be
>> reinitialised."
>>
>> This last sentence is the reason why RSA_new() will fail after you
>> have previously called >OPENSSL_cleanup().
>>
>> Because cleanup happens on process exit, OpenSSL will keep itself
>> in memory until that time >(otherwise crashes will occur because
>> the cleanup routines have been unloaded).
>>
>> If you want to dynamically load and unload your DLL then don't
>> statically link it to OpenSSL - >otherwise OpenSSL will keep your
>> DLL around until process exit too.
>>
>> Matt
>
> That is very disappointing.  As a library vendor we have no control
> over how our users load and unload our libraries.  We will just have
> to roll back to 1.0.x and wait to see if this will be addressed.
> Also, as Jakob stated in another post, it really seems like this
> design will be problematic.

Can you not link against the OpenSSL DLLs rather than statically link?
That would avoid the problem.

Matt


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Ryan Murray
Do you have a moment to edit or review my error 

Ryan Murray

On Jan 6, 2017 10:55 AM, "Matt Caswell" <[hidden email]> wrote:


On 06/01/17 14:36, Dan Heinz wrote:
>>> On 04/01/17 23:11, Dan Heinz wrote: Using openssl 1.1.0c.
>>>
>>> I have a test application that is a win32 console app that calls
>>> a win32 DLL which has the openssl libraries linked in
>>> statically.
>>>
>>> The test applications uses late-binding to the DLL and calls
>>> LoadLibrary for the DLL, one test function in the DLL, and then
>>> FreeLibrary on the DLL.
>>>
>>>
>>>
>>> The test function in the DLL does the following:
>>>
>>> RSA*rsa = NULL;
>>>
>>> rsa = RSA_new();
>>>
>>> RSA_free(rsa);
>>>
>>> OPENSSL_thread_stop();
>>>
>>> OPENSSL_cleanup();
>>>
>>> return0;
>>>
>>> When FreeLibrary is called on the DLL, dllmain in never called
>>> with any messages.  A subsequent call to LoadLibrary also fails
>>> to call dllmain and when the test function is called RSA_new()
>>> fails.  This leads me to believe the DLL is never freed.
>>>
>>> I have tried building openssl with and without no-threads with
>>> the same results.  My build parameters are: perl Configure
>>> *%TEMP_ARCHITECTURE%*
>>> --prefix=*%RootPath_ThirdParty%*\*%OPENSSL_VERSION%* -DPURIFY
>>> -DOPENSSL_NO_COMP -D_USING_V110_SDK71_ no-shared no-threads
>>> no-asm no-idea no-mdc2 no-rc5  no-ssl3 no-zlib no-comp
>>>
>>> What am I missing?
>>
>>
>> OpenSSL does its cleanup at *process* exit. Don't call
>> OPENSSL_cleanup() explicitly - this is >discouraged.
>>
>> From this manpage:
>>
>> https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html
>>
>>
>>
"Typically there should be no need to call this function directly as it
is initiated >automatically on application exit...<snip>...
>>
>> Once OPENSSL_cleanup() has been called the library cannot be
>> reinitialised."
>>
>> This last sentence is the reason why RSA_new() will fail after you
>> have previously called >OPENSSL_cleanup().
>>
>> Because cleanup happens on process exit, OpenSSL will keep itself
>> in memory until that time >(otherwise crashes will occur because
>> the cleanup routines have been unloaded).
>>
>> If you want to dynamically load and unload your DLL then don't
>> statically link it to OpenSSL - >otherwise OpenSSL will keep your
>> DLL around until process exit too.
>>
>> Matt
>
> That is very disappointing.  As a library vendor we have no control
> over how our users load and unload our libraries.  We will just have
> to roll back to 1.0.x and wait to see if this will be addressed.
> Also, as Jakob stated in another post, it really seems like this
> design will be problematic.

Can you not link against the OpenSSL DLLs rather than statically link?
That would avoid the problem.

Matt


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Michael Wojcik
In reply to this post by Matt Caswell-2
>
> Can you not link against the OpenSSL DLLs rather than statically link?
> That would avoid the problem.

It introduces other problems. It means either shipping the OpenSSL DLLs or requiring the customer provide them; the former can have legal implications (cryptographic export licensing, for example), while the latter is a usability issue. It means the calling library no longer controls what version of OpenSSL is used, since the DLLs can be replaced.

I haven't looked at the 1.1.x source to see what OPENSSL_cleanup is doing, but it certainly sounds like a bad idea. What kind of cleanup needs to happen at process exit (in the typical environment in which OpenSSL is used)? I suppose I'll have to take a look at the source, but I'd be very interested to hear the rationale.

Michael Wojcik
Distinguished Engineer, Micro Focus



--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Matt Caswell-2


On 06/01/17 16:37, Michael Wojcik wrote:

>>
>> Can you not link against the OpenSSL DLLs rather than statically
>> link? That would avoid the problem.
>
> It introduces other problems. It means either shipping the OpenSSL
> DLLs or requiring the customer provide them; the former can have
> legal implications (cryptographic export licensing, for example),
> while the latter is a usability issue. It means the calling library
> no longer controls what version of OpenSSL is used, since the DLLs
> can be replaced.
>
> I haven't looked at the 1.1.x source to see what OPENSSL_cleanup is
> doing, but it certainly sounds like a bad idea. What kind of cleanup
> needs to happen at process exit (in the typical environment in which
> OpenSSL is used)? I suppose I'll have to take a look at the source,
> but I'd be very interested to hear the rationale.

The problem is that OpenSSL uses global state extensively. Additionally,
you may get more than one component of an application using OpenSSL at
the same time, e.g. the application could use it, as well as libraries
that the application is linked against. In OpenSSL <1.1.0 we had (lots
of) explicit cleanup routines. This was a problem in this scenario
because you could end up with one component cleaning stuff up that
another component was still using.

Initially our atexit cleanup was nicer and got called when the last
reference to OpenSSL got unloaded. However, while this worked nicely on
some platforms, it wasn't portable and caused problems (crashes).
There's a long discussion on the problem and some of the solutions we
looked at here:

https://github.com/openssl/openssl/pull/1693

and more briefly here:

https://github.com/openssl/openssl/pull/1690

An example of the issue we were trying to solve is here:

https://github.com/curl/curl/issues/1055

I'm wondering whether an option to override the default behaviour might
be possible, e.g. an explicit call to OPENSSL_init_crypto() with
something like an OPENSSL_INIT_NO_ATEXIT_CLEANUP option. The application
would then have to call OPENSSL_cleanup() explicitly. This brings back
all the same problems with multiple components all using OpenSSL - but
perhaps you know this isn't a problem for your particular application
(especially if you are using static linking).

Matt

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Michael Wojcik
>
> I'm wondering whether an option to override the default behaviour might
> be possible, e.g. an explicit call to OPENSSL_init_crypto() with
> something like an OPENSSL_INIT_NO_ATEXIT_CLEANUP option. The
> application would then have to call OPENSSL_cleanup() explicitly.

Or not, because cleaning up resources immediately before process termination is usually a waste of time.

Michael Wojcik
Distinguished Engineer, Micro Focus
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Openssl static build linked in DLL does not unload on win32

Dan Heinz
In reply to this post by Matt Caswell-2
>>>> On 04/01/17 23:11, Dan Heinz wrote: Using openssl 1.1.0c.
>>>>
>>>> I have a test application that is a win32 console app that calls a >
>>> win32 DLL which has the openssl libraries linked in statically>.
>>>>
>>>> The test applications uses late-binding to the DLL and calls
>>>> LoadLibrary for the DLL, one test function in the DLL, and then
>>>> FreeLibrary on the DLL.>
>>>>
>>>>
>>>>
>>>> The test function in the DLL does the following:>
>>>>
>>>> RSA*rsa = NULL;
>>>>
>>>> rsa = RSA_new();>
>>>>
>>>> RSA_free(rsa);
>>>>
>>>> OPENSSL_thread_stop();>
>>>>
>>>> OPENSSL_cleanup();
>>>>
>>>> return0;>
>>>>
>>>> When FreeLibrary is called on the DLL, dllmain in never called with
>>>> any messages.  A subsequent call to LoadLibrary also fails to call
>>>> dllmain and when the test function is called RSA_new() fails.  This >
>>> leads me to believe the DLL is never freed>.
>>>>
>>>> I have tried building openssl with and without no-threads with the
>>>> same results.  My build parameters are: perl Configure
>>>> *%TEMP_ARCHITECTURE%*>
>>> --prefix=*%RootPath_T>hirdParty%*\*%OPENSSL_VERSION%* -DPURIFY
>>> -DOPENSSL_NO_COMP -D>_USING_V110_SDK71_ no-shared no-threads no-asm
>>> no-idea no-mdc2 no->rc5  no-ssl3 no-zlib no-comp
>>>>
>>>> What am I missing?
>>>
>>> >
>> >OpenSSL does its cleanup at *process* exit. Don't call
>>> OPENSSL_cleanup() explicitly - this is >discouraged.
>>>
>>> From this manpage:>
>>>
>>> https://www.openssl.org/docs/man1.1.0/crypto/OPENSSL_init_crypto.html
>>>>
>>>>
>>>>
"Ty>pically there should be no need to call this function directly as it is initiated >a>utomatically on application exit...<snip>...

>>>
>>> Once OPENSSL_cleanup() has been called the library cannot be >
>>> reinitialised.>"
>>>
>>> This last sentence is the reason why RSA_new() will fail after you
>>> have previously called >OPENSSL_cleanup().>
>>>
>>> Because cleanup happens on process exit, OpenSSL will keep itself in
>>> memory until that time >(otherwise crashes will occur because the >
>>> cleanup routines have been unloaded)>.
>>>
>>> If you want to dynamically load and unload your DLL then don't
>>> statically link it to OpenSSL - >otherwise OpenSSL will keep your DLL >
>>> around until process exit too>.
>>>
>>> Matt
>>>
>>That is very disappointing.  As a library vendor we have no control
>> over how our users load and unload our libraries.  We will just have
>> to roll back to 1.0.x and wait to see if this will be addressed.
>> Also, as Jakob stated in another post, it really seems like this
>> design will be problematic.
>
>Can you not link against the OpenSSL DLLs rather than statically link?
>That would avoid the problem.

Unfortunately, no.  We need to control the version of OpenSSL, and our users generally do not wish to have to distribute another DLL.  In addition, the static link adds a bit more protection from tampering.  I see you posted a link elsewhere to the discussion regarding this decision and I will examine it.  Being able to explicitly initialize and exit the library would certainly fix the issue for us and most likely others who will run into this same issue.

Thanks,
Dan

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Loading...