Skip to content

Commit 3e1d800

Browse files
committed
potential fix for windows static linking with thread creation in dll's
1 parent 312ce6f commit 3e1d800

File tree

4 files changed

+38
-9
lines changed

4 files changed

+38
-9
lines changed

include/mimalloc-internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ void _mi_error_message(int err, const char* fmt, ...);
6060

6161
// random.c
6262
void _mi_random_init(mi_random_ctx_t* ctx);
63+
void _mi_random_init_weak(mi_random_ctx_t* ctx);
64+
void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx);
6365
void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);
6466
uintptr_t _mi_random_next(mi_random_ctx_t* ctx);
6567
uintptr_t _mi_heap_random_next(mi_heap_t* heap);

include/mimalloc-types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ typedef struct mi_random_cxt_s {
357357
uint32_t input[16];
358358
uint32_t output[16];
359359
int output_available;
360+
bool weak;
360361
} mi_random_ctx_t;
361362

362363

src/init.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,13 @@ mi_stats_t _mi_stats_main = { MI_STATS_NULL };
142142
static void mi_heap_main_init(void) {
143143
if (_mi_heap_main.cookie == 0) {
144144
_mi_heap_main.thread_id = _mi_thread_id();
145-
_mi_heap_main.cookie = _mi_os_random_weak((uintptr_t)&mi_heap_main_init);
146-
_mi_random_init(&_mi_heap_main.random);
145+
_mi_heap_main.cookie = 1;
146+
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
147+
_mi_random_init_weak(&_mi_heap_main.random); // prevent allocation failure during bcrypt dll initialization with static linking
148+
#else
149+
_mi_random_init(&_mi_heap_main.random);
150+
#endif
151+
_mi_heap_main.cookie = _mi_heap_random_next(&_mi_heap_main);
147152
_mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main);
148153
_mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main);
149154
}
@@ -502,12 +507,13 @@ static void mi_process_load(void) {
502507
MI_UNUSED(dummy);
503508
#endif
504509
os_preloading = false;
510+
mi_assert_internal(_mi_is_main_thread());
505511
#if !(defined(_WIN32) && defined(MI_SHARED_LIB)) // use Dll process detach (see below) instead of atexit (issue #521)
506512
atexit(&mi_process_done);
507513
#endif
508514
_mi_options_init();
509-
mi_process_init();
510-
//mi_stats_reset();-
515+
mi_process_setup_auto_thread_done();
516+
mi_process_init();
511517
if (mi_redirected) _mi_verbose_message("malloc is redirected.\n");
512518

513519
// show message from the redirector (if present)
@@ -516,6 +522,9 @@ static void mi_process_load(void) {
516522
if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) {
517523
_mi_fputs(NULL,NULL,NULL,msg);
518524
}
525+
526+
// reseed random
527+
_mi_random_reinit_if_weak(&_mi_heap_main.random);
519528
}
520529

521530
#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
@@ -542,7 +551,6 @@ void mi_process_init(void) mi_attr_noexcept {
542551
_mi_process_is_initialized = true;
543552
mi_process_setup_auto_thread_done();
544553

545-
546554
mi_detect_cpu_features();
547555
_mi_os_init();
548556
mi_heap_main_init();

src/random.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ If we cannot get good randomness, we fall back to weak randomness based on a tim
168168

169169
#if defined(_WIN32)
170170

171-
#if defined(MI_USE_RTLGENRANDOM) || defined(__cplusplus)
171+
#if defined(MI_USE_RTLGENRANDOM) // || defined(__cplusplus)
172172
// We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using
173173
// dynamic overriding, we observed it can raise an exception when compiled with C++, and
174174
// sometimes deadlocks when also running under the VS debugger.
@@ -303,23 +303,41 @@ uintptr_t _mi_os_random_weak(uintptr_t extra_seed) {
303303
return x;
304304
}
305305

306-
void _mi_random_init(mi_random_ctx_t* ctx) {
306+
static void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) {
307307
uint8_t key[32];
308-
if (!os_random_buf(key, sizeof(key))) {
308+
if (use_weak || !os_random_buf(key, sizeof(key))) {
309309
// if we fail to get random data from the OS, we fall back to a
310310
// weak random source based on the current time
311311
#if !defined(__wasi__)
312-
_mi_warning_message("unable to use secure randomness\n");
312+
if (!use_weak) { _mi_warning_message("unable to use secure randomness\n"); }
313313
#endif
314314
uintptr_t x = _mi_os_random_weak(0);
315315
for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words.
316316
x = _mi_random_shuffle(x);
317317
((uint32_t*)key)[i] = (uint32_t)x;
318318
}
319+
ctx->weak = true;
320+
}
321+
else {
322+
ctx->weak = false;
319323
}
320324
chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ );
321325
}
322326

327+
void _mi_random_init(mi_random_ctx_t* ctx) {
328+
mi_random_init_ex(ctx, false);
329+
}
330+
331+
void _mi_random_init_weak(mi_random_ctx_t * ctx) {
332+
mi_random_init_ex(ctx, true);
333+
}
334+
335+
void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx) {
336+
if (ctx->weak) {
337+
_mi_random_init(ctx);
338+
}
339+
}
340+
323341
/* --------------------------------------------------------
324342
test vectors from <https://tools.ietf.org/html/rfc8439>
325343
----------------------------------------------------------- */

0 commit comments

Comments
 (0)