curl/lib/dllmain.c
Jay Satiro 7860f575fe dllmain: Call OpenSSL thread cleanup for Windows and Cygwin
- Call OPENSSL_thread_stop on thread termination (DLL_THREAD_DETACH)
  to prevent a memory leak in case OpenSSL is linked statically.

- Warn in libcurl-thread.3 that if OpenSSL is linked statically then it
  may require thread cleanup.

OpenSSL may need per-thread cleanup to stop a memory leak. For Windows
and Cygwin if libcurl was built as a DLL then we can do that for the
user by calling OPENSSL_thread_stop on thread termination. However, if
libcurl was built statically then we do not have notification of thread
termination and cannot do that for the user.

Also, there are several other unusual cases where it may be necessary
for the user to call OPENSSL_thread_stop, so in the libcurl-thread
warning I added a link to the OpenSSL documentation.

Co-authored-by: Viktor Szakats

Reported-by: southernedge@users.noreply.github.com
Reported-by: zmcx16@users.noreply.github.com

Ref: https://www.openssl.org/docs/man3.0/man3/OPENSSL_thread_stop.html#NOTES

Fixes https://github.com/curl/curl/issues/12327
Closes https://github.com/curl/curl/pull/12408
2024-04-24 04:04:25 -04:00

82 lines
2.4 KiB
C

/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_OPENSSL
#include <openssl/crypto.h>
#endif
/* The fourth-to-last include */
#ifdef __CYGWIN__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef _WIN32
#undef _WIN32
#endif
#endif
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
/* DllMain() must only be defined for Windows and Cygwin DLL builds. */
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(CURL_STATICLIB)
#if defined(USE_OPENSSL) && \
!defined(OPENSSL_IS_AWSLC) && \
!defined(OPENSSL_IS_BORINGSSL) && \
!defined(LIBRESSL_VERSION_NUMBER) && \
(OPENSSL_VERSION_NUMBER >= 0x10100000L)
#define PREVENT_OPENSSL_MEMLEAK
#endif
#ifdef PREVENT_OPENSSL_MEMLEAK
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
(void)hinstDLL;
(void)lpvReserved;
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
/* Call OPENSSL_thread_stop to prevent a memory leak in case OpenSSL is
linked statically.
https://github.com/curl/curl/issues/12327#issuecomment-1826405944 */
OPENSSL_thread_stop();
break;
}
return TRUE;
}
#endif /* OpenSSL */
#endif /* DLL build */