Skip to content

Conversation

@dscho
Copy link
Member

@dscho dscho commented Dec 18, 2025

Similar to 1475d9f (mimalloc: use "weak" random seed when statically linked, 2023-05-12) (which was actually already applied upstream in microsoft/mimalloc@3e1d800e (potential fix for windows static linking with thread creation in dll's, 2022-11-07), this ensures that another code path uses "weak" random seeds when initializing mimalloc.

The scenario when this happens is likely the exact same as back when the original fix was implemented (but I can only hypothesize about this, as I was unable to find a reproducer in my setup, and even the reporters could not find a reliable reproducer, either): an atexit() handler is called after mimalloc's own atexit() handler deinitializes mimalloc. This atexit() handler (namely post_command_hook_atexit()) then calls getenv(), which internally resolves to mingw_getenv(), which wants to calloc() the result so that it is not overwritten while in use. This, in turn, uses mimalloc, which dutifully initializes the random seed. It apparently takes a different code path than back in 2023, though, where it now tries to initialize a strong random generator implemented in bcrypt.dll. However, that initialization fails because it happens during the phase when only atexit() handlers are called, and bcrypt has obviously already been deinitialized, in a way that causes a crash.

The stack trace in question looks like this:

ntdll!ZwWaitForMultipleObjects+0x140 ...
KERNELBASE!WaitForMultipleObjectsEx+0x123 ...
KERNELBASE!WaitForMultipleObjects+0x11 ...
kernel32!WerpReportFaultInternal+0x62c ...
kernel32!WerpReportFault+0xc5 ...
KERNELBASE!UnhandledExceptionFilter+0x34c ...
ntdll!RtlpThreadExceptionFilter+0x2e ...
ntdll!RtlUserThreadStart$filt$0+0x3f0 ...
ntdll !_ C_specific_handler+0x93 ...
ntdll!RtlpExecuteHandlerForException+0xf ...
ntdll!RtlDispatchException+0x437 ...
ntdll!KiUserExceptionDispatch+0x2e() ...
bcryptPrimitives!AesRNGState_generate+0x79 ...
bcryptPrimitives!GenRandomAes+0xf70 ...
bcryptPrimitives!MSCryptGenRandom+0x15f ...
bcrypt!BCryptGenRandom+0x7a ...
bcrypt!BCryptGenSysternPreferredRandom+0x340 ....
bcrypt!BCryptGenRandom+0x119 ...
git!_ mi_prim_random_buf+0x23() [compat\mimalloc\prim\windows\prim.c @ 648]
git!mi_random_init_ex+0x61() [compat\mimalloc\random.c @ 179]
git!_ mi_heap_init+0xe8() [compat\mimalloc\heap.c @ 226]
git!mi_thread_init+0x21b() [compat\mimalloc\init.c @ 396]
git!mi_heap_get_default+0x9() [compat\mimalloc\mimalloc\prim.h @ 415]
git!_ mi_malloc_generic+0x9d() [compat\mimalloc\page.c @ 993]
git!mingw_getenv+0x4f() [compat\mingw.c @ 2446]
git!run_post_command_hook+0x84() [git.c @ 515]

Let's treat this code path in the exact same way as the code path in mi_heap_main_init().

Similar to 1475d9f (mimalloc: use "weak" random seed when
statically linked, 2023-05-12) (which was actually already applied
upstream in microsoft/mimalloc@3e1d800e
(potential fix for windows static linking with thread creation in dll's,
2022-11-07), this ensures that another code path uses "weak" random
seeds when initializing mimalloc.

The scenario when this happens is likely the exact same as back when
the original fix was implemented (but I can only hypothesize about this,
as I was unable to find a reproducer in my setup, and even the reporters
could not find a reliable reproducer, either): an `atexit()` handler
is called after mimalloc's own `atexit()` handler deinitializes
mimalloc. This `atexit()` handler (namely `post_command_hook_atexit()`)
then calls `getenv()`, which internally resolves to `mingw_getenv()`,
which wants to `calloc()` the result so that it is not overwritten
while in use. This, in turn, uses mimalloc, which dutifully initializes
the random seed. It apparently takes a different code path than back in
2023, though, where it now tries to initialize a strong random generator
implemented in bcrypt.dll. However, that initialization fails because
it happens during the phase when only `atexit()` handlers are called,
and bcrypt has obviously already been deinitialized, in a way that
causes a crash.

The stack trace in question looks like this:

 ntdll!ZwWaitForMultipleObjects+0x140 ...
 KERNELBASE!WaitForMultipleObjectsEx+0x123 ...
 KERNELBASE!WaitForMultipleObjects+0x11 ...
 kernel32!WerpReportFaultInternal+0x62c ...
 kernel32!WerpReportFault+0xc5 ...
 KERNELBASE!UnhandledExceptionFilter+0x34c ...
 ntdll!RtlpThreadExceptionFilter+0x2e ...
 ntdll!RtlUserThreadStart$filt$0+0x3f0 ...
 ntdll !_ C_specific_handler+0x93 ...
 ntdll!RtlpExecuteHandlerForException+0xf ...
 ntdll!RtlDispatchException+0x437 ...
 ntdll!KiUserExceptionDispatch+0x2e() ...
 bcryptPrimitives!AesRNGState_generate+0x79 ...
 bcryptPrimitives!GenRandomAes+0xf70 ...
 bcryptPrimitives!MSCryptGenRandom+0x15f ...
 bcrypt!BCryptGenRandom+0x7a ...
 bcrypt!BCryptGenSysternPreferredRandom+0x340 ....
 bcrypt!BCryptGenRandom+0x119 ...
 git!_ mi_prim_random_buf+0x23() [compat\mimalloc\prim\windows\prim.c @ 648]
 git!mi_random_init_ex+0x61() [compat\mimalloc\random.c @ 179]
 git!_ mi_heap_init+0xe8() [compat\mimalloc\heap.c @ 226]
 git!mi_thread_init+0x21b() [compat\mimalloc\init.c @ 396]
 git!mi_heap_get_default+0x9() [compat\mimalloc\mimalloc\prim.h @ 415]
 git!_ mi_malloc_generic+0x9d() [compat\mimalloc\page.c @ 993]
 git!mingw_getenv+0x4f() [compat\mingw.c @ 2446]
 git!run_post_command_hook+0x84() [git.c @ 515]

Let's treat this code path in the exact same way as the code path in
`mi_heap_main_init()`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho
Copy link
Member Author

dscho commented Dec 18, 2025

Please ignore the build-git-installers failures; They stem from the attempt to build the test release.

@dscho dscho enabled auto-merge December 18, 2025 15:25
@dscho
Copy link
Member Author

dscho commented Dec 18, 2025

I am upstreaming this patch to the mimalloc project in microsoft/mimalloc#1185.

@dscho dscho merged commit e64a68a into vfs-2.51.2 Dec 18, 2025
208 of 233 checks passed
@dscho dscho deleted the fix-mimalloc-crash-in-post-command branch December 18, 2025 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants