crypto/init.c: use destructor_key even as guard in OPENSSL_thread_stop.#6752
crypto/init.c: use destructor_key even as guard in OPENSSL_thread_stop.#6752dot-asm wants to merge 11 commits intoopenssl:masterfrom
Conversation
Problem was that Windows threads that were terminating before libcrypto was initialized were referencing uninitialized or possibly even unrelated thread local storage index.
| else if (ossl_isxdigit(ossl_tolower(c))) | ||
| return c - 'a' + 10; | ||
|
|
||
| return 16; |
There was a problem hiding this comment.
It's largest possible base value, that will make caller terminate to the loop. Added commentary.
crypto/init.c
Outdated
| static void ossl_init_thread_stop(struct thread_local_inits_st *locals); | ||
| /* | ||
| * Since per-thread-specific-data destructors are not universally | ||
| * available, i.e. not on *cough*-dows, only below CRYPTO_THREAD_LOCAL |
| * agnostic" means that they work with either wide or 8-bit characters, | ||
| * exploiting the fact that first 127 characters can be simply casted | ||
| * between the sets, while the rest would be simply rejected by ossl_is* | ||
| * subroutines. |
There was a problem hiding this comment.
I'm not sure how this is supposed to work. You get a char *. Every 2 characters will be a '\0' if it's UTF-16
There was a problem hiding this comment.
I must have somehow missed the ossl_char
There was a problem hiding this comment.
How about renaming ossl_char to variant_char? Hopefully it would be harder to miss then...
crypto/cryptlib.c
Outdated
| static WCHAR value[48]; | ||
| DWORD len = GetEnvironmentVariableW(L"OPENSSL_ia32cap", value, 48); | ||
|
|
||
| return (len > 0 && len <= 48) ? value : NULL; |
There was a problem hiding this comment.
As far as I understand, you can never get 48 back. But I would expect the check to be < 48.
There was a problem hiding this comment.
Oh! I thought that it returns value that accounts even for trailing null. But it does so only when buffer is not large enough. Thanks for spotting this!
crypto/cryptlib.c
Outdated
| */ | ||
| # ifdef _WIN32 | ||
| typedef WCHAR ossl_char; | ||
| static ossl_char *ossl_getenv(const char *name) |
There was a problem hiding this comment.
The name parameter is unused ...
There was a problem hiding this comment.
Correct. Basically there are two alternatives to this. a) Make conversion from char to WCHAR with MutliByteToWideChar in this subroutine. b) Arrange preprocessor directives so that "OPENSSL_ia32cap" literal is passed to ossl_getenv as L"OPENSSL_ia32cap" on Windows. Chosen approach (of ignoring the argument and resorting to hard-coded L-literal that works with specifically here) is least-typing one. Would a commentary be sufficient of should I switch to alternative?
|
|
||
| CRYPTO_THREAD_cleanup_local(&threadstopkey); | ||
| key = destructor_key; | ||
| destructor_key = (CRYPTO_THREAD_LOCAL)-1; |
There was a problem hiding this comment.
To denote the fact that it's no longer valid. Since libcrypto leaks descriptor to itself (not fan of it by the way), it won't go away from memory, so that Windows will keep invoking DLL_THREAD_DETACH and OPENSSL_thread_stop even after OPENSSL_cleanup. So that destructor_key has to go back to "impossible" value.
There was a problem hiding this comment.
I've mentioned post-cleanup case in commentary to destructor_key.
|
Feedback is addressed. |
|
Spotted bug in todigit! |
|
I've spotted typo in commentary, MSCVRT vs. MSVCRT, which fixed in first post-approval commit. Since it's commentary-only change I claim that it doesn't invalidate approval status (unless somebody claims otherwise). But on top of that I did ossl_char -> variant_char rename, which certainly invalidates approval status. However! I leave lack of re-approval as option. In sense that [if] request is not re-approved with variant_char, then I intend to merge commits up to this last one. |
|
I don't really care how you name that type, so consider this +1. |
There might be better options. "variant" can be used as adjective and does describe something that can change depending on situation. In this case depending on whether or not code is compiled for Windows. |
Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from #6752)
Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from #6752)
Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from #6752)
Problem was that Windows threads that were terminating before libcrypto was initialized were referencing uninitialized or possibly even unrelated thread local storage index. Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from #6752)
|
9e4a1c3 was the only that cherry-picked to 1.1.0. So that will be branch-specific requests... |
Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from openssl#6752) (cherry picked from commit b86d57b) Resolved conflicts: crypto/cryptlib.c
Problem was that Windows threads that were terminating before libcrypto was initialized were referencing uninitialized or possibly even unrelated thread local storage index. Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from openssl#6752) (cherry picked from commit 80ae728) Resolved conflicts: crypto/init.c
Problem was that Windows threads that were terminating before libcrypto
was initialized were referencing uninitialized or possibly even
unrelated thread local storage index.
Request covers even couple of other issues related to dllmain. This is alternative to #6627 and #6711.
1.0.2 and 1.1.0 labels are speculative in sense that not everything should be back-ported and those commits that should be won't necessarily cherry-pick.