Skip to content

heap-use-after-free running functions from profiling.sampling in free-threaded build #144567

@devdanzin

Description

@devdanzin

Crash report

What happened?

It's possible to non-deterministically (but with high probability) crash an ASan FT build by running the code below.

It might just be a case of setlocale not being thread safe, as per #127081. If so, sorry about the noise.

from threading import Thread
from time import sleep
import profiling.sampling.__main__ as main_module

alive = []
def task():
    main_module.main()
    sleep(0.006)
    main_module.main()
    main_module.handle_permission_error()
    sleep(0.008)
    main_module.handle_permission_error()
    main_module.main()
    sleep(0.005)
    main_module.main()


for x in range(500):
    alive.append(Thread(target=task))

for t in alive:
    t.start()
ASan output

=================================================================
==93518==ERROR: AddressSanitizer: heap-use-after-free on address 0x747131e54f70 at pc 0x785133082a88 bp 0x744f6af9e940 sp 0x744f6af9e0f8
READ of size 3 at 0x747131e54f70 thread T302
    #0 0x785133082a87 in strlen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:425
    #1 0x63fbfffd0312 in PyUnicode_DecodeLocale Objects/unicodeobject.c:3947
    #2 0x63fc0038bb30 in _locale_setlocale_impl Modules/_localemodule.c:172
    #3 0x63fc0038bd8d in _locale_setlocale Modules/clinic/_localemodule.c.h:55
    #4 0x63fc000b8fe8 in _Py_BuiltinCallFast_StackRefSteal Python/ceval.c:812
    #5 0x63fc000cb08a in _PyEval_EvalFrameDefault Python/generated_cases.c.h:2319
    #6 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #7 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #8 0x63fbffe0f9eb in _PyFunction_Vectorcall Objects/call.c:413
    #9 0x63fbffe15f47 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #10 0x63fbffe16400 in method_vectorcall Objects/classobject.c:73
    #11 0x63fc001401e9 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #12 0x63fc001413f6 in context_run Python/context.c:727
    #13 0x63fc000b981b in _PyCallMethodDescriptorFastWithKeywords_StackRefSteal Python/ceval.c:913
    #14 0x63fc000d1e6a in _PyEval_EvalFrameDefault Python/generated_cases.c.h:3820
    #15 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #16 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #17 0x63fbffe0f9eb in _PyFunction_Vectorcall Objects/call.c:413
    #18 0x63fbffe15f47 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #19 0x63fbffe16400 in method_vectorcall Objects/classobject.c:73
    #20 0x63fbffe130d4 in _PyVectorcall_Call Objects/call.c:273
    #21 0x63fbffe135ae in _PyObject_Call Objects/call.c:348
    #22 0x63fbffe135f4 in PyObject_Call Objects/call.c:373
    #23 0x63fc00374050 in thread_run Modules/_threadmodule.c:387
    #24 0x63fc0023fcf6 in pythread_wrapper Python/thread_pthread.h:234
    #25 0x78513305f802 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:239
    #26 0x785132ca3d63 in start_thread nptl/pthread_create.c:448
    #27 0x785132d373fb in __clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

0x747131e54f70 is located 0 bytes inside of 8-byte region [0x747131e54f70,0x747131e54f78)
freed by thread T303 here:
    #0 0x78513312114b in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:51
    #1 0x785132c3b549 in setname locale/setlocale.c:199
    #2 0x785132c3b549 in __GI_setlocale locale/setlocale.c:385
    #3 0x63fc0038bb1b in _locale_setlocale_impl Modules/_localemodule.c:165
    #4 0x63fc0038bd8d in _locale_setlocale Modules/clinic/_localemodule.c.h:55
    #5 0x63fc000b8fe8 in _Py_BuiltinCallFast_StackRefSteal Python/ceval.c:812
    #6 0x63fc000cb08a in _PyEval_EvalFrameDefault Python/generated_cases.c.h:2319
    #7 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #8 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #9 0x63fbffe0f9eb in _PyFunction_Vectorcall Objects/call.c:413
    #10 0x63fbffe15f47 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #11 0x63fbffe16400 in method_vectorcall Objects/classobject.c:73
    #12 0x63fc001401e9 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #13 0x63fc001413f6 in context_run Python/context.c:727
    #14 0x63fc000b981b in _PyCallMethodDescriptorFastWithKeywords_StackRefSteal Python/ceval.c:913
    #15 0x63fc000d1e6a in _PyEval_EvalFrameDefault Python/generated_cases.c.h:3820
    #16 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #17 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #18 0x63fbffe0f9eb in _PyFunction_Vectorcall Objects/call.c:413
    #19 0x63fbffe15f47 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #20 0x63fbffe16400 in method_vectorcall Objects/classobject.c:73
    #21 0x63fbffe130d4 in _PyVectorcall_Call Objects/call.c:273
    #22 0x63fbffe135ae in _PyObject_Call Objects/call.c:348
    #23 0x63fbffe135f4 in PyObject_Call Objects/call.c:373
    #24 0x63fc00374050 in thread_run Modules/_threadmodule.c:387
    #25 0x63fc0023fcf6 in pythread_wrapper Python/thread_pthread.h:234
    #26 0x78513305f802 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:239
    #27 0x785132ca3d63 in start_thread nptl/pthread_create.c:448

previously allocated by thread T302 here:
    #0 0x78513312261b in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:67
    #1 0x785132c3b15b in new_composite_name locale/setlocale.c:165
    #2 0x785132c3b345 in __GI_setlocale locale/setlocale.c:375
    #3 0x63fc0038bb1b in _locale_setlocale_impl Modules/_localemodule.c:165
    #4 0x63fc0038bd8d in _locale_setlocale Modules/clinic/_localemodule.c.h:55
    #5 0x63fc000b8fe8 in _Py_BuiltinCallFast_StackRefSteal Python/ceval.c:812
    #6 0x63fc000cb08a in _PyEval_EvalFrameDefault Python/generated_cases.c.h:2319
    #7 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #8 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #9 0x63fbffe0f9eb in _PyFunction_Vectorcall Objects/call.c:413
    #10 0x63fbffe15f47 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #11 0x63fbffe16400 in method_vectorcall Objects/classobject.c:73
    #12 0x63fc001401e9 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #13 0x63fc001413f6 in context_run Python/context.c:727
    #14 0x63fc000b981b in _PyCallMethodDescriptorFastWithKeywords_StackRefSteal Python/ceval.c:913
    #15 0x63fc000d1e6a in _PyEval_EvalFrameDefault Python/generated_cases.c.h:3820
    #16 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #17 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #18 0x63fbffe0f9eb in _PyFunction_Vectorcall Objects/call.c:413
    #19 0x63fbffe15f47 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:136
    #20 0x63fbffe16400 in method_vectorcall Objects/classobject.c:73
    #21 0x63fbffe130d4 in _PyVectorcall_Call Objects/call.c:273
    #22 0x63fbffe135ae in _PyObject_Call Objects/call.c:348
    #23 0x63fbffe135f4 in PyObject_Call Objects/call.c:373
    #24 0x63fc00374050 in thread_run Modules/_threadmodule.c:387
    #25 0x63fc0023fcf6 in pythread_wrapper Python/thread_pthread.h:234
    #26 0x78513305f802 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:239
    #27 0x785132ca3d63 in start_thread nptl/pthread_create.c:448

Thread T302 created by T0 here:
    #0 0x7851331196aa in pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:250
    #1 0x63fc0024043e in do_start_joinable_thread Python/thread_pthread.h:281
    #2 0x63fc00240875 in PyThread_start_joinable_thread Python/thread_pthread.h:323
    #3 0x63fc00373587 in ThreadHandle_start Modules/_threadmodule.c:474
    #4 0x63fc00373931 in do_start_new_thread Modules/_threadmodule.c:1920
    #5 0x63fc00373d10 in thread_PyThread_start_joinable_thread Modules/_threadmodule.c:2043
    #6 0x63fbffed7af2 in cfunction_call Objects/methodobject.c:564
    #7 0x63fbffe0fca4 in _PyObject_MakeTpCall Objects/call.c:242
    #8 0x63fbffe0ff4c in _PyObject_VectorcallTstate Include/internal/pycore_call.h:134
    #9 0x63fbffe0ffa5 in PyObject_Vectorcall Objects/call.c:327
    #10 0x63fc000b890a in _Py_VectorCall_StackRefSteal Python/ceval.c:720
    #11 0x63fc000cfca3 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:3363
    #12 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #13 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #14 0x63fc0010110f in PyEval_EvalCode Python/ceval.c:673
    #15 0x63fc0020ba40 in run_eval_code_obj Python/pythonrun.c:1366
    #16 0x63fc0020bde0 in run_mod Python/pythonrun.c:1469
    #17 0x63fc0020ce12 in pyrun_file Python/pythonrun.c:1294
    #18 0x63fc0020fc45 in _PyRun_SimpleFileObject Python/pythonrun.c:518
    #19 0x63fc0020fef1 in _PyRun_AnyFileObject Python/pythonrun.c:81
    #20 0x63fc00267f6c in pymain_run_file_obj Modules/main.c:410
    #21 0x63fc002681d1 in pymain_run_file Modules/main.c:429
    #22 0x63fc002699cd in pymain_run_python Modules/main.c:691
    #23 0x63fc0026a09f in Py_RunMain Modules/main.c:772
    #24 0x63fc0026a28b in pymain_main Modules/main.c:802
    #25 0x63fc0026a669 in Py_BytesMain Modules/main.c:826
    #26 0x63fbffc9d675 in main Programs/python.c:15
    #27 0x785132c2a574 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #28 0x785132c2a627 in __libc_start_main_impl ../csu/libc-start.c:360
    #29 0x63fbffc9d5a4 in _start (/home/danzin/projects/ft_cpython/python+0x2e55a4) (BuildId: ce254dfc811aaeffb4186beb96972c10b03e6035)

Thread T303 created by T0 here:
    #0 0x7851331196aa in pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:250
    #1 0x63fc0024043e in do_start_joinable_thread Python/thread_pthread.h:281
    #2 0x63fc00240875 in PyThread_start_joinable_thread Python/thread_pthread.h:323
    #3 0x63fc00373587 in ThreadHandle_start Modules/_threadmodule.c:474
    #4 0x63fc00373931 in do_start_new_thread Modules/_threadmodule.c:1920
    #5 0x63fc00373d10 in thread_PyThread_start_joinable_thread Modules/_threadmodule.c:2043
    #6 0x63fbffed7af2 in cfunction_call Objects/methodobject.c:564
    #7 0x63fbffe0fca4 in _PyObject_MakeTpCall Objects/call.c:242
    #8 0x63fbffe0ff4c in _PyObject_VectorcallTstate Include/internal/pycore_call.h:134
    #9 0x63fbffe0ffa5 in PyObject_Vectorcall Objects/call.c:327
    #10 0x63fc000b890a in _Py_VectorCall_StackRefSteal Python/ceval.c:720
    #11 0x63fc000cfca3 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:3363
    #12 0x63fc00100aff in _PyEval_EvalFrame Include/internal/pycore_ceval.h:118
    #13 0x63fc00100e65 in _PyEval_Vector Python/ceval.c:2092
    #14 0x63fc0010110f in PyEval_EvalCode Python/ceval.c:673
    #15 0x63fc0020ba40 in run_eval_code_obj Python/pythonrun.c:1366
    #16 0x63fc0020bde0 in run_mod Python/pythonrun.c:1469
    #17 0x63fc0020ce12 in pyrun_file Python/pythonrun.c:1294
    #18 0x63fc0020fc45 in _PyRun_SimpleFileObject Python/pythonrun.c:518
    #19 0x63fc0020fef1 in _PyRun_AnyFileObject Python/pythonrun.c:81
    #20 0x63fc00267f6c in pymain_run_file_obj Modules/main.c:410
    #21 0x63fc002681d1 in pymain_run_file Modules/main.c:429
    #22 0x63fc002699cd in pymain_run_python Modules/main.c:691
    #23 0x63fc0026a09f in Py_RunMain Modules/main.c:772
    #24 0x63fc0026a28b in pymain_main Modules/main.c:802
    #25 0x63fc0026a669 in Py_BytesMain Modules/main.c:826
    #26 0x63fbffc9d675 in main Programs/python.c:15
    #27 0x785132c2a574 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #28 0x785132c2a627 in __libc_start_main_impl ../csu/libc-start.c:360
    #29 0x63fbffc9d5a4 in _start (/home/danzin/projects/ft_cpython/python+0x2e55a4) (BuildId: ce254dfc811aaeffb4186beb96972c10b03e6035)

SUMMARY: AddressSanitizer: heap-use-after-free Objects/unicodeobject.c:3947 in PyUnicode_DecodeLocale
Shadow bytes around the buggy address:
  0x747131e54c80: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x747131e54d00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x747131e54d80: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x747131e54e00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x747131e54e80: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x747131e54f00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa[fd]fa
  0x747131e54f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x747131e55000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x747131e55080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x747131e55100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x747131e55180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==93518==ABORTING

Found using fusil by @vstinner.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

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

Python 3.15.0a5+ free-threading build (heads/main:a2495ff1e7b, Feb 7 2026, 09:23:37) [GCC 15.2.0]

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-free-threadingtype-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