compat/mimalloc/init.c: use weak random seed when statically linked (#580)

Always use the internal "use_weak" random seed when initializing the
"mimalloc" heap when statically linked on Windows.

The imported "mimalloc" routines support several random sources to seed
the heap data structures, including BCrypt.dll and RtlGenRandom. Crashes
have been reported when using BCrypt.dll if it initialized during an
`atexit()` handler function. Granted, such DLL initialization should not
happen in an atexit handler, but yet the crashes remain.

It should be noted that on Windows when statically linked, the mimalloc
startup code (called by the GCC CRT to initialize static data prior to
calling `main()`) always uses the internal "weak" random seed.
"mimalloc" does not try to load an alternate random source until after
the OS initialization has completed.

Heap data is stored in `__declspec(thread)` TLS data and in theory each
Git thread will have its own heap data. However, testing shows that the
"mimalloc" library doesn't actually call `os_random_buf()` (to load a
new random source) when creating these new per-thread heap structures.

However, if an atexit handler is forced to run on a non-main thread, the
"mimalloc" library *WILL* try to create a new heap and seed it with
`os_random_buf()`. (The reason for this is still a mystery to this
author.) The `os_random_buf()` call can cause the (previously
uninitialized BCrypt.dll library) to be dynamically loaded and a call
made into it. Crashes have been reported in v2.40.1.vfs.0.0 while in
this call.

As a workaround, the fix here forces the use of the internal "use_weak"
random code for the subsequent `os_random_buf()` calls. Since we have
been using that random generator for the majority of the program, it
seems safe to use it for the final few mallocs in the atexit handler (of
which there really shouldn't be that many.

This fix should go into upstream git-for-windows eventually. I'm
flighting it here in a special v240.1.vfs.0.1
so that we can confirm that it addresses the crash seen by GVFS/Scalar
users with v2.40.1.vfs.0.0.
This commit is contained in:
Jeff Hostetler 2023-05-15 10:44:07 -04:00 коммит произвёл GitHub
Родитель 27f6460705 d6b89206f3
Коммит 98346fc3f9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 4 добавлений и 0 удалений

Просмотреть файл

@ -278,7 +278,11 @@ static bool _mi_heap_init(void) {
_mi_memcpy_aligned(tld, &tld_empty, sizeof(*tld));
_mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(*heap));
heap->thread_id = _mi_thread_id();
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
_mi_random_init_weak(&heap->random); // match mi_heap_main_init()
#else
_mi_random_init(&heap->random);
#endif
heap->cookie = _mi_heap_random_next(heap) | 1;
heap->keys[0] = _mi_heap_random_next(heap);
heap->keys[1] = _mi_heap_random_next(heap);