Avoid UB (member call on nullptr) when failing to read randomness in the startup process#15111
Avoid UB (member call on nullptr) when failing to read randomness in the startup process#15111practicalswift wants to merge 1 commit intobitcoin:masterfrom
Conversation
… in the startup process
|
I fail to see how About the randomness failure: We should probably not consume bytes before we did a Could you clarify how this is happening and maybe include steps to reproduce? |
|
@MarcoFalke After #14955 the initialization of the RNG happens on first use, even before calling |
|
@MarcoFalke Consider the case when the PRNG has not been seeded with enough randomness to ensure an unpredictable byte sequence. Give me a few minutes I'll get back with the exact steps to reproduce. |
|
Steps to reproduce: Please note: before That answers the raised questions? |
|
@MarcoFalke @sipa These are places I've identified (so far) where randomness is requested before
|
|
It seems odd that we need those globals (e.g. the mempool) before |
|
@MarcoFalke That would be nice. And |
|
There are generally two ways of dealing with initialization order of globals. One is to make all globals unique_ptrs or otherwise non-instantiated at startup and explicitly create all. Another approach is using std::call_once or static locals like #14955 does. Since C++11 the second can be done with pretty low overhead and without too big hoops, so that's my preference over explicit initialization as it's less fragile. |
|
@sipa Do you agree that |
|
What is even the point of g_logger in the first place? It seems to serve no purpose except creating UB when logging is called by global constructors. I propose instead PR#12954 be reverted: It served no obvious purpose and instead introduced a potentially serious misbehaviour. |
|
@MarcoFalke Could this one get a release milestone? :-) |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
Closing in favour of @MarcoFalke's better fix in #15266. Thanks! |
77777c5 log: Construct global logger on first use (MarcoFalke) Pull request description: The (de)initialization order is not well defined in C++, so generally it is not safe to use globals as the (de/con)structor of one global could use the (de/con)structor of another global before/after it has been (con/de)structed. Specifically this fixes: * `g_logger` might not be initialized on the first use, so do that. (Fixes bitcoin#15111) Tree-SHA512: eb9c22f4baf31ebc5b0b9ee6a51d1354bae1f0df186cc0ce818b4483c7b5a7f90268d2b549ee96b4c57f8ef36ab239dc6497f74f3e2ef166038f7437c368297d
77777c5 log: Construct global logger on first use (MarcoFalke) Pull request description: The (de)initialization order is not well defined in C++, so generally it is not safe to use globals as the (de/con)structor of one global could use the (de/con)structor of another global before/after it has been (con/de)structed. Specifically this fixes: * `g_logger` might not be initialized on the first use, so do that. (Fixes bitcoin#15111) Tree-SHA512: eb9c22f4baf31ebc5b0b9ee6a51d1354bae1f0df186cc0ce818b4483c7b5a7f90268d2b549ee96b4c57f8ef36ab239dc6497f74f3e2ef166038f7437c368297d
77777c5 log: Construct global logger on first use (MarcoFalke) Pull request description: The (de)initialization order is not well defined in C++, so generally it is not safe to use globals as the (de/con)structor of one global could use the (de/con)structor of another global before/after it has been (con/de)structed. Specifically this fixes: * `g_logger` might not be initialized on the first use, so do that. (Fixes bitcoin#15111) Tree-SHA512: eb9c22f4baf31ebc5b0b9ee6a51d1354bae1f0df186cc0ce818b4483c7b5a7f90268d2b549ee96b4c57f8ef36ab239dc6497f74f3e2ef166038f7437c368297d
77777c5 log: Construct global logger on first use (MarcoFalke) Pull request description: The (de)initialization order is not well defined in C++, so generally it is not safe to use globals as the (de/con)structor of one global could use the (de/con)structor of another global before/after it has been (con/de)structed. Specifically this fixes: * `g_logger` might not be initialized on the first use, so do that. (Fixes bitcoin#15111) Tree-SHA512: eb9c22f4baf31ebc5b0b9ee6a51d1354bae1f0df186cc0ce818b4483c7b5a7f90268d2b549ee96b4c57f8ef36ab239dc6497f74f3e2ef166038f7437c368297d
Avoid UB (member call on
nullptr) when failing to read randomness in the startup process.RandFailureis called byGetDevURandom,GetOSRandandGetRandByteswhen failing to read randomness for some reason.This is
RandFailure:This is
LogPrintf:Compilers are allowed to optimise away calls to
RandFailurethat are guaranteed to take place wheng_logger == nullptr. Please note that such optimisation would remove the crucialstd::abortcall inRandFailure.Failing to read randomness before this patch (under UBSan):
Failing to read randomness after this patch (under UBSan):