This transaction appears to have no contentIn looking at this further, I note that even in a static lib build of OpenSSL, the OPENSSL_cpuid_setup() function is putin the CRT$XCU segment that is to be executed as part of static global initializations. Anything that runs like that is subject to the same issues as whatever runs in DllMain() is, so this means that this same getenv() deadlock problem can also occur even if the OpenSSL library itself is static, rather than a DLL.
- Michael
On Feb 26, 2011, Michael M. Welch <[email protected]> wrote:
Platform: Windows only
Version: OpenSSL 1.0.0d
Source file: crypto\cryptlib.c
Function: OPENSSL_cpuid_setup() ( invoked from within DllMain() )
Llines: 677 and 678
Source:
if ((env=getenv("OPENSSL_ia32cap")))
OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
Problem:
Per this website ( http://msdn.microsoft.com/en-us/library/ms682583%28v=vs.85%29.aspx ), Microsoft is on record as stating that calling CRT methods from within DllMain() is inherently unsafe and can lead to deadlock situations in multi-threaded applications. The example on the given website cautions about getenv() specifically.
In OpenSSL crypto, the getenv() function is explicitly invoked during DllMain(), thus opening up this dangerous situation. (Furthermore, it's immediately followed by a call to strtoul(), another CRT function.) Deadlocks ensue when one thread runs the DllMain, thus acquiring the LoaderLock and then looks to acquire _ENV_LOCK (because getenv() requires that lock), but another thread already has _ENV_LOCK and is looking to acquire the LoaderLock.
- Michael
