Skip to content

Non-CPython segfault on os.exec*e and os.spawn*e (_wexec*e, _spawn*e) from Windows UCRT #137934

@bswck

Description

@bswck

Crash report

Problem

It is possible to get a segfault using os.exec*e and os.spawn*e functions on Windows.

construct_environment_block from ucrtbase.dll causes an access violation on Windows (at least: Windows 10, Server 2022 and Server 2025) during _wexec*e and _wspawn*e CRT calls. _exec*e and _spawn*e functions were not tested for this segfault.

Notes

Possibly related to GH-67650 (exec*e crashes) and GH-74094 (spawnve crashes).

This is not a CPython bug, but active CPython releases are affected.

Reproduction

Python

import os

prog = r"C:\Windows\System32\whoami.exe"
os.execve(prog, [prog], os.environ)

Python correctly parses the envlist argument to os_execve_impl and the crash is not caused by CPython, as explained below.

Important

Run the script directly using the Python binary.
Running from python.bat will not reproduce the issue.

To simplify, {"foo": "bar"} were used as the environment argument (and ucrtbased.dll as the UCRT DLL):

import os

prog = r"C:\Windows\System32\whoami.exe"
os.execve(prog, [prog], {"foo": "bar"})

Stack trace, running in MSYS2 bash:

ModLoad: 00007ff6`4c290000 00007ff6`4c2b7000   python_d.exe
ModLoad: 00007ffb`4cb10000 00007ffb`4cd08000   ntdll.dll
ModLoad: 00007ffb`4b730000 00007ffb`4b7f2000   C:\Windows\System32\KERNEL32.DLL
ModLoad: 00007ffb`4a660000 00007ffb`4a957000   C:\Windows\System32\KERNELBASE.dll
ModLoad: 00007ffb`22ea0000 00007ffb`22ed0000   C:\Windows\SYSTEM32\VCRUNTIME140D.dll
ModLoad: 00007ffa`a65d0000 00007ffa`a67ef000   C:\Windows\SYSTEM32\ucrtbased.dll
ModLoad: 0000023c`50c10000 0000023c`50e2f000   C:\Windows\SYSTEM32\ucrtbased.dll
ModLoad: 00007ffa`8e3d0000 00007ffa`8f1a0000   C:\Users\zenon\Python\cpython\PCbuild\amd64\python315_d.dll
ModLoad: 00007ffb`4bd00000 00007ffb`4bd6b000   C:\Windows\System32\WS2_32.dll
ModLoad: 00007ffb`37f80000 00007ffb`37f8a000   C:\Windows\SYSTEM32\VERSION.dll
ModLoad: 00007ffb`4bd90000 00007ffb`4beb6000   C:\Windows\System32\RPCRT4.dll
ModLoad: 00007ffb`4c7b0000 00007ffb`4c84e000   C:\Windows\System32\msvcrt.dll
ModLoad: 00007ffb`4a5a0000 00007ffb`4a5c7000   C:\Windows\System32\bcrypt.dll
ModLoad: 00007ffb`4b480000 00007ffb`4b531000   C:\Windows\System32\ADVAPI32.dll
ModLoad: 00007ffb`4ca30000 00007ffb`4cacf000   C:\Windows\System32\sechost.dll
(70c0.7a9c): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`4cbe07a0 cc              int     3
0:000> g
ModLoad: 00007ffb`4a5d0000 00007ffb`4a652000   C:\Windows\System32\bcryptprimitives.dll
(70c0.7a9c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ucrtbased!<lambda_34e583b68fdec51c841899eb9e58770b>::operator()+0x20:
00007ffa`a660a8e0 0fb700          movzx   eax,word ptr [rax] ds:0000023c`51262000=????
0:000> kp
Child-SP          RetAddr               Call Site
0000009c`4b5799b0 00007ffa`a660a410     ucrtbased!<lambda_34e583b68fdec51c841899eb9e58770b>::operator()(void)+0x20
0000009c`4b579a00 00007ffa`a660898d     ucrtbased!construct_environment_block<wchar_t>(wchar_t ** envp = 0x0000023c`50c88460, wchar_t ** environment_block_result = 0x0000009c`4b579b98)+0x290
0000009c`4b579b60 00007ffa`a6608781     ucrtbased!common_pack_argv_and_envp<wchar_t>(wchar_t ** argv = 0x0000023c`50c88c10, wchar_t ** envp = 0x0000023c`50c88460, wchar_t ** command_line_result = 0x0000009c`4b579c70, wchar_t ** environment_block_result = 0x0000009c`4b579c68)+0x7d
0000009c`4b579bb0 00007ffa`a660f55d     ucrtbased!__acrt_pack_wide_command_line_and_environment(wchar_t ** argv = 0x0000023c`50c88c10, wchar_t ** envp = 0x0000023c`50c88460, wchar_t ** command_line_result = 0x0000009c`4b579c70, wchar_t ** environment_block_result = 0x0000009c`4b579c68)+0x31
0000009c`4b579be0 00007ffa`a660ee8d     ucrtbased!__crt_char_traits<wchar_t>::pack_command_line_and_environment<wchar_t const * const * const &,wchar_t const * const * const &,wchar_t * *,wchar_t * *>(wchar_t *** <args_0> = 0x0000009c`4b579df0, wchar_t *** <args_1> = 0x0000009c`4b579df8, wchar_t *** <args_2> = 0x0000009c`4b579cc0, wchar_t *** <args_3> = 0x0000009c`4b579cb8)+0x3d
0000009c`4b579c10 00007ffa`a660dec8     ucrtbased!execute_command<wchar_t>(int mode = 0n2, wchar_t * file_name = 0x0000023c`51045e40 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x0000023c`50c88c10, wchar_t ** environment = 0x0000023c`50c88460)+0x2cd
0000009c`4b579de0 00007ffa`a660cdec     ucrtbased!common_spawnv<wchar_t>(int mode = 0n2, wchar_t * file_name = 0x0000023c`51045e40 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x0000023c`50c88c10, wchar_t ** environment = 0x0000023c`50c88460)+0x688
*** WARNING: Unable to verify checksum for C:\Users\zenon\Python\cpython\PCbuild\amd64\python315_d.dll
0000009c`4b579f20 00007ffa`8e61916f     ucrtbased!_wexecve(wchar_t * file_name = 0x0000023c`51045e40 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x0000023c`50c88c10, wchar_t ** environment = 0x0000023c`50c88460)+0x2c
0000009c`4b579f50 00007ffa`8e60af5c     python315_d!os_execve_impl(struct _object * module = 0x0000023c`50f6ef90, struct path_t * path = 0x0000009c`4b57a060, struct _object * argv = 0x0000023c`50d05360, struct _object * env = 0x0000023c`50fd5430)+0x25f
0000009c`4b579ff0 00007ffa`8e7bbbc4     python315_d!os_execve(struct _object * module = 0x0000023c`50f6ef90, struct _object ** args = 0x0000009c`4b57f1b8, int64 nargs = 0n3, struct _object * kwnames = 0x00000000`00000000)+0x20c
0000009c`4b57a0f0 00007ffa`8e6fc432     python315_d!cfunction_vectorcall_FASTCALL_KEYWORDS(struct _object * func = 0x0000023c`50f6fad0, struct _object ** args = 0x0000009c`4b57f1b8, unsigned int64 nargsf = 0x80000000`00000003, struct _object * kwnames = 0x00000000`00000000)+0xd4
0000009c`4b57a160 00007ffa`8e6f9ee8     python315_d!_PyObject_VectorcallTstate(struct _ts * tstate = 0x00007ffa`8f1771a8, struct _object * callable = 0x0000023c`50f6fad0, struct _object ** args = 0x0000009c`4b57f1b8, unsigned int64 nargsf = 0x80000000`00000003, struct _object * kwnames = 0x00000000`00000000)+0x172
0000009c`4b57a1e0 00007ffa`8ea3eb76     python315_d!PyObject_Vectorcall(struct _object * callable = 0x0000023c`50f6fad0, struct _object ** args = 0x0000009c`4b57f1b8, unsigned int64 nargsf = 0x80000000`00000003, struct _object * kwnames = 0x00000000`00000000)+0x68
0000009c`4b57a230 00007ffa`8ea87686     python315_d!_PyEval_EvalFrameDefault(struct _ts * tstate = 0x00007ffa`8f1771a8, struct _PyInterpreterFrame * frame = 0x0000023c`50a90020, int throwflag = 0n0)+0x7b76
0000009c`4b57f5f0 00007ffa`8ea32729     python315_d!_PyEval_Vector(struct _ts * tstate = 0x00007ffa`8f1771a8, struct PyFunctionObject * func = 0x0000023c`50fc6bd0, struct _object * locals = 0x0000023c`50fd5370, struct _object ** args = 0x00000000`00000000, unsigned int64 argcount = 0, struct _object * kwnames = 0x00000000`00000000)+0x226
0000009c`4b57f6d0 00007ffa`8ec139d7     python315_d!PyEval_EvalCode(struct _object * co = 0x0000023c`50c63940, struct _object * globals = 0x0000023c`50fd5370, struct _object * locals 
= 0x0000023c`50fd5370)+0x149
0000009c`4b57f780 00007ffa`8ec13d26     python315_d!run_eval_code_obj(struct _ts * tstate = 0x00007ffa`8f1771a8, struct PyCodeObject * co = 0x0000023c`50c63940, struct _object * globals = 0x0000023c`50fd5370, struct _object * locals = 0x0000023c`50fd5370)+0xe7
0000009c`4b57f7d0 00007ffa`8ec132b3     python315_d!run_mod(struct _mod * mod = 0x0000023c`512530f8, struct _object * filename = 0x0000023c`50f7bca0, struct _object * globals = 0x0000023c`50fd5370, struct _object * locals = 0x0000023c`50fd5370, struct PyCompilerFlags * flags = 0x0000009c`4b57fa38, struct _arena * arena = 0x0000023c`51045d20, struct _object * interactive_src = 0x00000000`00000000, int generate_new_source = 0n0)+0x306
0000009c`4b57f860 00007ffa`8ec10e0b     python315_d!pyrun_file(struct _iobuf * fp = 0x0000023c`50bffb40, struct _object * filename = 0x0000023c`50f7bca0, int start = 0n257, struct _object * globals = 0x0000023c`50fd5370, struct _object * locals = 0x0000023c`50fd5370, int closeit = 0n1, struct PyCompilerFlags * flags = 0x0000009c`4b57fa38)+0xf3
0000009c`4b57f8e0 00007ffa`8ec10821     python315_d!_PyRun_SimpleFileObject(struct _iobuf * fp = 0x0000023c`50bffb40, struct _object * filename = 0x0000023c`50f7bca0, int closeit = 0n1, struct PyCompilerFlags * flags = 0x0000009c`4b57fa38)+0x2cb
0000009c`4b57f9a0 00007ffa`8e5e3eab     python315_d!_PyRun_AnyFileObject(struct _iobuf * fp = 0x0000023c`50bffb40, struct _object * filename = 0x0000023c`50f7bca0, int closeit = 0n1, 
struct PyCompilerFlags * flags = 0x0000009c`4b57fa38)+0xb1
0000009c`4b57f9e0 00007ffa`8e5e3c8f     python315_d!pymain_run_file_obj(struct _object * program_name = 0x0000023c`51000c40, struct _object * filename = 0x0000023c`50f7bca0, int skip_source_first_line = 0n0)+0x1ab
0000009c`4b57fae0 00007ffa`8e5e45c4     python315_d!pymain_run_file(struct PyConfig * config = 0x00007ffa`8f142248)+0x9f
0000009c`4b57fb30 00007ffa`8e5e2b10     python315_d!pymain_run_python(int * exitcode = 0x0000009c`4b57fc10)+0x324
0000009c`4b57fbf0 00007ffa`8e5e37c2     python315_d!Py_RunMain(void)+0x20
0000009c`4b57fc30 00007ffa`8e5e2acc     python315_d!pymain_main(struct _PyArgv * args = 0x0000009c`4b57fcf0)+0x72
*** WARNING: Unable to verify checksum for python_d.exe
0000009c`4b57fcd0 00007ff6`4c29141b     python315_d!Py_Main(int argc = 0n2, wchar_t ** argv = 0x0000023c`50b1a450)+0x3c
0000009c`4b57fd20 00007ff6`4c291819     python_d!wmain(int argc = 0n2, wchar_t ** argv = 0x0000023c`50b1a450)+0x1b
0000009c`4b57fd50 00007ff6`4c2916c2     python_d!invoke_main(void)+0x39
0000009c`4b57fda0 00007ff6`4c29157e     python_d!__scrt_common_main_seh(void)+0x132
0000009c`4b57fe10 00007ff6`4c2918ae     python_d!__scrt_common_main(void)+0xe
0000009c`4b57fe40 00007ffb`4b747374     python_d!wmainCRTStartup(void * __formal = 0x0000009c`4a86f000)+0xe
0000009c`4b57fe70 00007ffb`4cb5cc91     KERNEL32!BaseThreadInitThunk+0x14
0000009c`4b57fea0 00000000`00000000     ntdll!RtlUserThreadStart+0x21

wchar_t ** envp at 0x0000023c`50c88460 is the envlist; here's the dump:

0:000> dps 0x0000023c`50c88460 L5
0000023c`50c88460  0000023c`50c88c70
0000023c`50c88468  00000000`00000000
0000023c`50c88470  fdfdfdfd`fdfdfdfd
0000023c`50c88478  dddddddd`dddddddd
0000023c`50c88480  10000000`00000000

This seems correct. First an env key-value pair string (see below), then a NUL, then malloc fence, then some free memory, and then some junk.

0:000> du 0000023c`50c88c70       
0000023c`50c88c70  "foo=bar"

To further confirm, the same script can be launched in cmd.exe and not crash:

ModLoad: 00007ff6`4c290000 00007ff6`4c2b7000   python_d.exe
ModLoad: 00007ffb`4cb10000 00007ffb`4cd08000   ntdll.dll
ModLoad: 00007ffb`4b730000 00007ffb`4b7f2000   C:\Windows\System32\KERNEL32.DLL
ModLoad: 00007ffb`4a660000 00007ffb`4a957000   C:\Windows\System32\KERNELBASE.dll
ModLoad: 00007ffa`d99a0000 00007ffa`d9bbf000   C:\Windows\SYSTEM32\ucrtbased.dll
ModLoad: 00007ffb`22ea0000 00007ffb`22ed0000   C:\Windows\SYSTEM32\VCRUNTIME140D.dll
ModLoad: 00007ffa`8e3d0000 00007ffa`8f1a0000   C:\Users\zenon\Python\cpython\PCbuild\amd64\python315_d.dll
ModLoad: 00007ffb`4bd00000 00007ffb`4bd6b000   C:\Windows\System32\WS2_32.dll
ModLoad: 00007ffb`4bd90000 00007ffb`4beb6000   C:\Windows\System32\RPCRT4.dll
ModLoad: 00007ffb`4a5a0000 00007ffb`4a5c7000   C:\Windows\System32\bcrypt.dll
ModLoad: 00007ffb`4b480000 00007ffb`4b531000   C:\Windows\System32\ADVAPI32.dll
ModLoad: 00007ffb`4c7b0000 00007ffb`4c84e000   C:\Windows\System32\msvcrt.dll
ModLoad: 00007ffb`4ca30000 00007ffb`4cacf000   C:\Windows\System32\sechost.dll
ModLoad: 00007ffb`37f80000 00007ffb`37f8a000   C:\Windows\SYSTEM32\VERSION.dll
(6908.1584): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`4cbe07a0 cc              int     3
0:000> bp ucrtbased!construct_environment_block<wchar_t>+0x207    
0:000> g
ModLoad: 00007ffb`4a5d0000 00007ffb`4a652000   C:\Windows\System32\bcryptprimitives.dll
Breakpoint 0 hit
ucrtbased!construct_environment_block<wchar_t>+0x207:
00007ffa`d99da387 e8c4fdffff      call    ucrtbased!<lambda_edb5ee1f814822daeafcbdde31b12fbf>::<lambda_edb5ee1f814822daeafcbdde31b12fbf> (00007ffa`d99da150)
0:000> kp
Child-SP          RetAddr               Call Site
0000009f`3b779620 00007ffa`d99d898d     ucrtbased!construct_environment_block<wchar_t>(wchar_t ** envp = 0x00000240`da598460, wchar_t ** environment_block_result = 0x0000009f`3b7797b8)+0x207
0000009f`3b779780 00007ffa`d99d8781     ucrtbased!common_pack_argv_and_envp<wchar_t>(wchar_t ** argv = 0x00000240`da598c10, wchar_t ** envp = 0x00000240`da598460, wchar_t ** command_line_result = 0x0000009f`3b779890, wchar_t ** environment_block_result = 0x0000009f`3b779888)+0x7d
0000009f`3b7797d0 00007ffa`d99df55d     ucrtbased!__acrt_pack_wide_command_line_and_environment(wchar_t ** argv = 0x00000240`da598c10, wchar_t ** envp = 0x00000240`da598460, wchar_t ** command_line_result = 0x0000009f`3b779890, wchar_t ** environment_block_result = 0x0000009f`3b779888)+0x31
0000009f`3b779800 00007ffa`d99dee8d     ucrtbased!__crt_char_traits<wchar_t>::pack_command_line_and_environment<wchar_t const * const * const &,wchar_t const * const * const &,wchar_t * *,wchar_t * *>(wchar_t *** <args_0> = 0x0000009f`3b779a10, wchar_t *** <args_1> = 0x0000009f`3b779a18, wchar_t *** <args_2> = 0x0000009f`3b7798e0, wchar_t *** <args_3> = 0x0000009f`3b7798d8)+0x3d
0000009f`3b779830 00007ffa`d99ddec8     ucrtbased!execute_command<wchar_t>(int mode = 0n2, wchar_t * file_name = 0x00000240`da865f00 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x00000240`da598c10, wchar_t ** environment = 0x00000240`da598460)+0x2cd
0000009f`3b779a00 00007ffa`d99dcdec     ucrtbased!common_spawnv<wchar_t>(int mode = 0n2, wchar_t * file_name = 0x00000240`da865f00 "C:\Windows\System32\whoami.exe", 
wchar_t ** arguments = 0x00000240`da598c10, wchar_t ** environment = 0x00000240`da598460)+0x688
*** WARNING: Unable to verify checksum for C:\Users\zenon\Python\cpython\PCbuild\amd64\python315_d.dll
0000009f`3b779b40 00007ffa`8e61916f     ucrtbased!_wexecve(wchar_t * file_name = 0x00000240`da865f00 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x00000240`da598c10, wchar_t ** environment = 0x00000240`da598460)+0x2c
0000009f`3b779b70 00007ffa`8e60af5c     python315_d!os_execve_impl(struct _object * module = 0x00000240`da78ef90, struct path_t * path = 0x0000009f`3b779c80, struct 
_object * argv = 0x00000240`da615360, struct _object * env = 0x00000240`da7f54f0)+0x25f
0000009f`3b779c10 00007ffa`8e7bbbc4     python315_d!os_execve(struct _object * module = 0x00000240`da78ef90, struct _object ** args = 0x0000009f`3b77edd8, int64 nargs = 0n3, struct _object * kwnames = 0x00000000`00000000)+0x20c
0000009f`3b779d10 00007ffa`8e6fc432     python315_d!cfunction_vectorcall_FASTCALL_KEYWORDS(struct _object * func = 0x00000240`da78fad0, struct _object ** args = 0x0000009f`3b77edd8, unsigned int64 nargsf = 0x80000000`00000003, struct _object * kwnames = 0x00000000`00000000)+0xd4
0000009f`3b779d80 00007ffa`8e6f9ee8     python315_d!_PyObject_VectorcallTstate(struct _ts * tstate = 0x00007ffa`8f1771a8, struct _object * callable = 0x00000240`da78fad0, struct _object ** args = 0x0000009f`3b77edd8, unsigned int64 nargsf = 0x80000000`00000003, struct _object * kwnames = 0x00000000`00000000)+0x172
0000009f`3b779e00 00007ffa`8ea3eb76     python315_d!PyObject_Vectorcall(struct _object * callable = 0x00000240`da78fad0, struct _object ** args = 0x0000009f`3b77edd8, unsigned int64 nargsf = 0x80000000`00000003, struct _object * kwnames = 0x00000000`00000000)+0x68
0000009f`3b779e50 00007ffa`8ea87686     python315_d!_PyEval_EvalFrameDefault(struct _ts * tstate = 0x00007ffa`8f1771a8, struct _PyInterpreterFrame * frame = 0x00000240`da3a0020, int throwflag = 0n0)+0x7b76
0000009f`3b77f210 00007ffa`8ea32729     python315_d!_PyEval_Vector(struct _ts * tstate = 0x00007ffa`8f1771a8, struct PyFunctionObject * func = 0x00000240`da7e6bd0, struct _object * locals = 0x00000240`da7f5430, struct _object ** args = 0x00000000`00000000, unsigned int64 argcount = 0, struct _object * kwnames = 0x00000000`00000000)+0x226
0000009f`3b77f2f0 00007ffa`8ec139d7     python315_d!PyEval_EvalCode(struct _object * co = 0x00000240`da573940, struct _object * globals = 0x00000240`da7f5430, struct _object * locals = 0x00000240`da7f5430)+0x149
0000009f`3b77f3a0 00007ffa`8ec13d26     python315_d!run_eval_code_obj(struct _ts * tstate = 0x00007ffa`8f1771a8, struct PyCodeObject * co = 0x00000240`da573940, struct _object * globals = 0x00000240`da7f5430, struct _object * locals = 0x00000240`da7f5430)+0xe7
0000009f`3b77f3f0 00007ffa`8ec132b3     python315_d!run_mod(struct _mod * mod = 0x00000240`da94d3e8, struct _object * filename = 0x00000240`da79bca0, struct _object 
* globals = 0x00000240`da7f5430, struct _object * locals = 0x00000240`da7f5430, struct PyCompilerFlags * flags = 0x0000009f`3b77f658, struct _arena * arena = 0x00000240`da865de0, struct _object * interactive_src = 0x00000000`00000000, int generate_new_source = 0n0)+0x306
0000009f`3b77f480 00007ffa`8ec10e0b     python315_d!pyrun_file(struct _iobuf * fp = 0x00000240`da50f600, struct _object * filename = 0x00000240`da79bca0, int start = 0n257, struct _object * globals = 0x00000240`da7f5430, struct _object * locals = 0x00000240`da7f5430, int closeit = 0n1, struct PyCompilerFlags * flags = 0x0000009f`3b77f658)+0xf3
0000009f`3b77f500 00007ffa`8ec10821     python315_d!_PyRun_SimpleFileObject(struct _iobuf * fp = 0x00000240`da50f600, struct _object * filename = 0x00000240`da79bca0, int closeit = 0n1, struct PyCompilerFlags * flags = 0x0000009f`3b77f658)+0x2cb
0000009f`3b77f5c0 00007ffa`8e5e3eab     python315_d!_PyRun_AnyFileObject(struct _iobuf * fp = 0x00000240`da50f600, struct _object * filename = 0x00000240`da79bca0, int closeit = 0n1, struct PyCompilerFlags * flags = 0x0000009f`3b77f658)+0xb1
0000009f`3b77f600 00007ffa`8e5e3c8f     python315_d!pymain_run_file_obj(struct _object * program_name = 0x00000240`da828bc0, struct _object * filename = 0x00000240`da79bca0, int skip_source_first_line = 0n0)+0x1ab
0000009f`3b77f700 00007ffa`8e5e45c4     python315_d!pymain_run_file(struct PyConfig * config = 0x00007ffa`8f142248)+0x9f
0000009f`3b77f750 00007ffa`8e5e2b10     python315_d!pymain_run_python(int * exitcode = 0x0000009f`3b77f830)+0x324
0000009f`3b77f810 00007ffa`8e5e37c2     python315_d!Py_RunMain(void)+0x20
0000009f`3b77f850 00007ffa`8e5e2acc     python315_d!pymain_main(struct _PyArgv * args = 0x0000009f`3b77f910)+0x72
*** WARNING: Unable to verify checksum for python_d.exe
0000009f`3b77f8f0 00007ff6`4c29141b     python315_d!Py_Main(int argc = 0n2, wchar_t ** argv = 0x00000240`da4285f0)+0x3c
0000009f`3b77f940 00007ff6`4c291819     python_d!wmain(int argc = 0n2, wchar_t ** argv = 0x00000240`da4285f0)+0x1b
0000009f`3b77f970 00007ff6`4c2916c2     python_d!invoke_main(void)+0x39
0000009f`3b77f9c0 00007ff6`4c29157e     python_d!__scrt_common_main_seh(void)+0x132
0000009f`3b77fa30 00007ff6`4c2918ae     python_d!__scrt_common_main(void)+0xe
0000009f`3b77fa60 00007ffb`4b747374     python_d!wmainCRTStartup(void * __formal = 0x0000009f`3aa0f000)+0xe
0000009f`3b77fa90 00007ffb`4cb5cc91     KERNEL32!BaseThreadInitThunk+0x14
0000009f`3b77fac0 00000000`00000000     ntdll!RtlUserThreadStart+0x21

Running using python.bat dodges the bullet as well.

envp:

0:000> dps 0x00000240`da598460 L5
00000240`da598460  00000240`da598c70
00000240`da598468  00000000`00000000
00000240`da598470  fdfdfdfd`fdfdfdfd
00000240`da598478  dddddddd`dddddddd
00000240`da598480  10000000`00000000
0:000> du 00000240`da598c70
00000240`da598c70  "foo=bar"

Looks identical.

This time it continues without crash:

0:000> g

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*
Symbol search path is: srv*
Executable search path is:
ModLoad: 00007ff6`30180000 00007ff6`30196000   whoami.exe
ModLoad: 00007ffb`489c0000 00007ffb`489d2000   C:\Windows\SYSTEM32\kernel.appcore.dll
ModLoad: 00007ffb`4cb10000 00007ffb`4cd08000   ntdll.dll
ModLoad: 00007ffb`4b730000 00007ffb`4b7f2000   C:\Windows\System32\KERNEL32.DLL
ModLoad: 00007ffb`4a660000 00007ffb`4a957000   C:\Windows\System32\KERNELBASE.dll
ModLoad: 00007ffb`4b480000 00007ffb`4b531000   C:\Windows\System32\ADVAPI32.dll
ModLoad: 00007ffb`4c7b0000 00007ffb`4c84e000   C:\Windows\System32\msvcrt.dll
ModLoad: 00007ffb`4ca30000 00007ffb`4cacf000   C:\Windows\System32\sechost.dll
ModLoad: 00007ffb`4bd90000 00007ffb`4beb6000   C:\Windows\System32\RPCRT4.dll
ModLoad: 00007ffb`4a5a0000 00007ffb`4a5c7000   C:\Windows\System32\bcrypt.dll
ModLoad: 00007ffb`4c610000 00007ffb`4c7ad000   C:\Windows\System32\USER32.dll
ModLoad: 00007ffb`4a960000 00007ffb`4a982000   C:\Windows\System32\win32u.dll
ModLoad: 00007ffb`4b800000 00007ffb`4b82b000   C:\Windows\System32\GDI32.dll
ModLoad: 00007ffb`4a480000 00007ffb`4a599000   C:\Windows\System32\gdi32full.dll
ModLoad: 00007ffb`4aa90000 00007ffb`4ab2d000   C:\Windows\System32\msvcp_win.dll
ModLoad: 00007ffb`4a990000 00007ffb`4aa90000   C:\Windows\System32\ucrtbase.dll
ModLoad: 00007ffb`4bd00000 00007ffb`4bd6b000   C:\Windows\System32\WS2_32.dll
ModLoad: 00007ffb`4b830000 00007ffb`4b88b000   C:\Windows\System32\SHLWAPI.dll
ModLoad: 00007ffb`37f80000 00007ffb`37f8a000   C:\Windows\System32\VERSION.dll
ModLoad: 00007ffb`48f00000 00007ffb`48f4f000   C:\Windows\System32\AUTHZ.dll
ModLoad: 00007ffb`4a080000 00007ffb`4a0b2000   C:\Windows\System32\SspiCli.dll
ModLoad: 00007ffb`49300000 00007ffb`49319000   C:\Windows\System32\wkscli.dll
ModLoad: 00007ffb`49600000 00007ffb`4960c000   C:\Windows\System32\netutils.dll
(75d0.7854): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`4cbe07a0 cc              int     3
1:004>

Versions affected are (at least) 3.9—main. I tested the reproduction on other systems; the issue lies only in Windows' UCRT.

Functions affected should include all those in posixmodule.c that exercise the path to ucrtbase!construct_environment_block,
so all os.exec*e functions and os.spawnle & os.spawnve.

I tested the crasher with 3.9—3.14.0rc2 Python versions and Microsoft Windows Server 2025 (10.0.26100) + Microsoft Windows Server 2022 (10.0.20348) OS runners. The results are here.

C

This C script reproduces the problem. The program below is correct.

/* t.c */
#include <windows.h>

int wmain(void) {
    const wchar_t *prog = L"C:\\Windows\\System32\\whoami.exe";
    const wchar_t *argv[] = { prog, NULL };
    const wchar_t *envp[] = { L"foo=bar", NULL };
    _wexecve(prog, argv, envp);
    return 0;
}

I compiled it on Windows 10 Pro (10.0.19045) using cl /Zi /MD t.c for testing ucrtbase.dll and cl /Zi /MDd t.c for more informative stack traces from ucrtbased.dll.

Stack trace (ucrtbase.dll):

ModLoad: 00007ff6`17150000 00007ff6`1715e000   t.exe
ModLoad: 00007ffb`4cb10000 00007ffb`4cd08000   ntdll.dll
ModLoad: 00007ffb`4b730000 00007ffb`4b7f2000   C:\Windows\System32\KERNEL32.DLL     
ModLoad: 00007ffb`4a660000 00007ffb`4a957000   C:\Windows\System32\KERNELBASE.dll   
ModLoad: 00007ffb`4a990000 00007ffb`4aa90000   C:\Windows\System32\ucrtbase.dll     
ModLoad: 00007ffa`b47f0000 00007ffa`b480e000   C:\Windows\SYSTEM32\VCRUNTIME140.dll 
(3be4.6ad0): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`4cbe07a0 cc              int     3
0:000> g
(3be4.6ad0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ucrtbase!construct_environment_block<wchar_t>+0x12a:
00007ffb`4aa3c4ce 6641395500      cmp     word ptr [r13],dx ds:0000016d`b070b000=????
0:000> kp
Child-SP          RetAddr               Call Site
00000045`20aff840 00007ffb`4aa3be11     ucrtbase!construct_environment_block<wchar_t>+0x12a
00000045`20aff900 00007ffb`4aa3d7ab     ucrtbase!common_pack_argv_and_envp<wchar_t>+0x4d
00000045`20aff940 00007ffb`4aa3d404     ucrtbase!execute_command<wchar_t>+0x7b      
*** WARNING: Unable to verify checksum for t.exe
00000045`20affa50 00007ff6`171513fc     ucrtbase!common_spawnv<wchar_t>+0x180
00000045`20affab0 00007ff6`17151654     t!wmain(void)+0x4c
(Inline Function) --------`--------     t!invoke_main(void)+0x22
00000045`20affb10 00007ffb`4b747374     t!__scrt_common_main_seh(void)+0x10c        
00000045`20affb50 00007ffb`4cb5cc91     KERNEL32!BaseThreadInitThunk+0x14
00000045`20affb80 00000000`00000000     ntdll!RtlUserThreadStart+0x21
0:000>

Stack trace (ucrtbased.dll):

ModLoad: 00007ff6`852b0000 00007ff6`852bf000   t.exe
ModLoad: 00007ffb`4cb10000 00007ffb`4cd08000   ntdll.dll
ModLoad: 00007ffb`4b730000 00007ffb`4b7f2000   C:\Windows\System32\KERNEL32.DLL     
ModLoad: 00007ffb`4a660000 00007ffb`4a957000   C:\Windows\System32\KERNELBASE.dll   
ModLoad: 00007ffb`22ea0000 00007ffb`22ed0000   C:\Windows\SYSTEM32\VCRUNTIME140D.dllModLoad: 00007ffa`d99a0000 00007ffa`d9bbf000   C:\Windows\SYSTEM32\ucrtbased.dll
(6d28.5e18): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`4cbe07a0 cc              int     3
0:000> g
(6d28.5e18): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ucrtbased!<lambda_34e583b68fdec51c841899eb9e58770b>::operator()+0x20:
00007ffa`d99da8e0 0fb700          movzx   eax,word ptr [rax] ds:00000191`576ef000=????
0:000> kp
Child-SP          RetAddr               Call Site
0000004e`ab7ef130 00007ffa`d99da410     ucrtbased!<lambda_34e583b68fdec51c841899eb9e58770b>::operator()(void)+0x20
0000004e`ab7ef180 00007ffa`d99d898d     ucrtbased!construct_environment_block<wchar_t>(wchar_t ** envp = 0x0000004e`ab7ef6f8, wchar_t ** environment_block_result = 0x0000004e`ab7ef318)+0x290
0000004e`ab7ef2e0 00007ffa`d99d8781     ucrtbased!common_pack_argv_and_envp<wchar_t>(wchar_t ** argv = 0x0000004e`ab7ef708, wchar_t ** envp = 0x0000004e`ab7ef6f8, wchar_t ** command_line_result = 0x0000004e`ab7ef3f0, wchar_t ** environment_block_result = 0x0000004e`ab7ef3e8)+0x7d
0000004e`ab7ef330 00007ffa`d99df55d     ucrtbased!__acrt_pack_wide_command_line_and_environment(wchar_t ** argv = 0x0000004e`ab7ef708, wchar_t ** envp = 0x0000004e`ab7ef6f8, wchar_t ** command_line_result = 0x0000004e`ab7ef3f0, wchar_t ** environment_block_result = 0x0000004e`ab7ef3e8)+0x31
0000004e`ab7ef360 00007ffa`d99dee8d     ucrtbased!__crt_char_traits<wchar_t>::pack_command_line_and_environment<wchar_t const * const * const &,wchar_t const * const * 
const &,wchar_t * *,wchar_t * *>(wchar_t *** <args_0> = 0x0000004e`ab7ef570, wchar_t *** <args_1> = 0x0000004e`ab7ef578, wchar_t *** <args_2> = 0x0000004e`ab7ef440, wchar_t *** <args_3> = 0x0000004e`ab7ef438)+0x3d
0000004e`ab7ef390 00007ffa`d99ddec8     ucrtbased!execute_command<wchar_t>(int mode 
= 0n2, wchar_t * file_name = 0x00007ff6`852ba000 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x0000004e`ab7ef708, wchar_t ** environment = 0x0000004e`ab7ef6f8)+0x2cd
0000004e`ab7ef560 00007ffa`d99dcdec     ucrtbased!common_spawnv<wchar_t>(int mode = 
0n2, wchar_t * file_name = 0x00007ff6`852ba000 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x0000004e`ab7ef708, wchar_t ** environment = 0x0000004e`ab7ef6f8)+0x688
*** WARNING: Unable to verify checksum for t.exe
0000004e`ab7ef6a0 00007ff6`852b144c     ucrtbased!_wexecve(wchar_t * file_name = 0x00007ff6`852ba000 "C:\Windows\System32\whoami.exe", wchar_t ** arguments = 0x0000004e`ab7ef708, wchar_t ** environment = 0x0000004e`ab7ef6f8)+0x2c
0000004e`ab7ef6d0 00007ff6`852b1a69     t!wmain(void)+0x4c
0000004e`ab7ef730 00007ff6`852b1912     t!invoke_main(void)+0x39
0000004e`ab7ef780 00007ff6`852b17ce     t!__scrt_common_main_seh(void)+0x132        
0000004e`ab7ef7f0 00007ff6`852b1afe     t!__scrt_common_main(void)+0xe
0000004e`ab7ef820 00007ffb`4b747374     t!wmainCRTStartup(void * __formal = 0x0000004e`ab95a000)+0xe
0000004e`ab7ef850 00007ffb`4cb5cc91     KERNEL32!BaseThreadInitThunk+0x14
0000004e`ab7ef880 00000000`00000000     ntdll!RtlUserThreadStart+0x21
0:000>

Running t.exe in cmd.exe doesn't crash as well.

Musings

All evidence suggests the crash depends on differences in the parent process environment.
Running Python from cmd.exe or via python.bat avoids the issue, possibly because the environment is inherited.
This still needs deeper investigation (I will complete my analysis in the coming days). I plan to bisect the differences between environment blocks.

All tests so far were on x86-64.
The affected range may extend back to Python 3.6–3.8.

CC @ZeroIntensity

CPython versions tested on:

3.9, CPython main branch, 3.15, 3.14, 3.13, 3.10, 3.11, 3.12

Operating systems tested on:

Linux, macOS, Windows

Output from running 'python -VV' on the command line:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowstype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions