Skip to content

JIT: Global buffer overflow in _PyUOpPrint when running with PYTHON_LLTRACE=4 #142629

@devdanzin

Description

@devdanzin

Crash report

What happened?

The 469f191 commit broke PYTHON_LLTRACE=4, causing what ASan diagnoses as a global buffer overflow. For instance, it will crash running this code:

def f():
    for x in range(1000):
        x + 1

for x in range(1000):
    f()

Here's the output along with the crash message:

PYTHON_LLTRACE=4 ./python lltrace_crash.py
Tracing f (/home/danzin/projects/jit_cpython/lltrace_crash.py:1) at byte offset 24 at chain depth 0
0x753b67e16f50 24: JUMP_BACKWARD(14) 0 2
   3 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=24, operand0=0, operand1=0xbebebebebebebebe)
   4 ADD_TO_TRACE: _SET_IP (0, target=24, operand0=0x753b67e17050, operand1=0xbebebebebebebebe)
   5 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=24, operand0=0, operand1=0xbebebebebebebebe, error_target=0)
Trace continuing
0x753b67e16f50 12: FOR_ITER_RANGE(12) 0 2
   6 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=12, operand0=0, operand1=0xbebebebebebebebe)
   7 ADD_TO_TRACE: _SET_IP (0, target=12, operand0=0x753b67e17038, operand1=0xbebebebebebebebe)
   8 ADD_TO_TRACE: _ITER_CHECK_RANGE (12, target=12, operand0=0, operand1=0xbebebebebebebebe)
   9 ADD_TO_TRACE: _GUARD_NOT_EXHAUSTED_RANGE (12, target=27, operand0=0, operand1=0xbebebebebebebebe)
  10 ADD_TO_TRACE: _ITER_NEXT_RANGE (12, target=12, operand0=0, operand1=0xbebebebebebebebe, error_target=0)
Trace continuing
0x753b67e16f50 14: STORE_FAST(0) 0 3
  11 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=14, operand0=0, operand1=0xbebebebebebebebe)
  12 ADD_TO_TRACE: _SET_IP (0, target=14, operand0=0x753b67e1703c, operand1=0xbebebebebebebebe)
  13 ADD_TO_TRACE: _STORE_FAST (0, target=14, operand0=0, operand1=0xbebebebebebebebe)
Trace continuing
0x753b67e16f50 15: LOAD_FAST_BORROW(0) 0 2
  14 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=15, operand0=0, operand1=0xbebebebebebebebe)
  15 ADD_TO_TRACE: _SET_IP (0, target=15, operand0=0x753b67e1703e, operand1=0xbebebebebebebebe)
  16 ADD_TO_TRACE: _LOAD_FAST_BORROW (0, target=15, operand0=0, operand1=0xbebebebebebebebe)
Trace continuing
0x753b67e16f50 16: LOAD_SMALL_INT(1) 0 3
  17 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=16, operand0=0, operand1=0xbebebebebebebebe)
  18 ADD_TO_TRACE: _SET_IP (0, target=16, operand0=0x753b67e17040, operand1=0xbebebebebebebebe)
  19 ADD_TO_TRACE: _LOAD_SMALL_INT (1, target=16, operand0=0, operand1=0xbebebebebebebebe)
Trace continuing
0x753b67e16f50 17: BINARY_OP_ADD_INT(0) 0 4
  20 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=17, operand0=0, operand1=0xbebebebebebebebe)
  21 ADD_TO_TRACE: _SET_IP (0, target=17, operand0=0x753b67e17042, operand1=0xbebebebebebebebe)
  22 ADD_TO_TRACE: _GUARD_TOS_INT (0, target=17, operand0=0, operand1=0xbebebebebebebebe)
  23 ADD_TO_TRACE: _GUARD_NOS_INT (0, target=17, operand0=0, operand1=0xbebebebebebebebe)
  24 ADD_TO_TRACE: _BINARY_OP_ADD_INT (0, target=17, operand0=0, operand1=0xbebebebebebebebe)
Trace continuing
0x753b67e16f50 23: POP_TOP(0) 0 3
  25 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=23, operand0=0, operand1=0xbebebebebebebebe)
  26 ADD_TO_TRACE: _SET_IP (0, target=23, operand0=0x753b67e1704e, operand1=0xbebebebebebebebe)
  27 ADD_TO_TRACE: _POP_TOP (0, target=23, operand0=0, operand1=0xbebebebebebebebe)
  28 ADD_TO_TRACE: _JUMP_TO_TOP (0, target=0, operand0=0, operand1=0xbebebebebebebebe)
Trace done
Optimized trace (length 26):
   0 OPTIMIZED: _START_EXECUTOR_r00 (0, jump_target=18, operand0=0x759b67e0c0a0, operand1=0xbebebebebebebebe)
   1 OPTIMIZED: _MAKE_WARM_r00 (0, target=0, operand0=0, operand1=0xbebebebebebebebe)
   2 OPTIMIZED: _SET_IP_r00 (0, target=24, operand0=0x753b67e17050, operand1=0xbebebebebebebebe)
=================================================================
==75165==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5d177abfc290 at pc 0x5d177a6557e3 bp 0x7ffdc19949d0 sp 0x7ffdc19949c8
READ of size 4 at 0x5d177abfc290 thread T0
    #0 0x5d177a6557e2 in _PyUOpPrint /home/danzin/projects/jit_cpython/Python/optimizer.c:359:9
    #1 0x5d177a65328f in make_executor_from_uops /home/danzin/projects/jit_cpython/Python/optimizer.c:1368:13
    #2 0x5d177a65328f in uop_optimize /home/danzin/projects/jit_cpython/Python/optimizer.c:1497:35
    #3 0x5d177a65328f in _PyOptimizer_Optimize /home/danzin/projects/jit_cpython/Python/optimizer.c:164:15
    #4 0x5d177a14ef53 in stop_tracing_and_jit /home/danzin/projects/jit_cpython/Python/ceval.c:1405:15
    #5 0x5d177a10debd in _PyEval_EvalFrameDefault /home/danzin/projects/jit_cpython/Python/generated_cases.c.h:11385:27
    #6 0x5d177a0e9817 in _PyEval_EvalFrame /home/danzin/projects/jit_cpython/./Include/internal/pycore_ceval.h:119:16
    #7 0x5d177a0e9817 in _PyEval_Vector /home/danzin/projects/jit_cpython/Python/ceval.c:2482:12
    #8 0x5d177a0e9234 in PyEval_EvalCode /home/danzin/projects/jit_cpython/Python/ceval.c:1008:21
    #9 0x5d177a6ea0ee in run_eval_code_obj /home/danzin/projects/jit_cpython/Python/pythonrun.c:1372:12
    #10 0x5d177a6e92bb in run_mod /home/danzin/projects/jit_cpython/Python/pythonrun.c:1475:19
    #11 0x5d177a6e38bc in pyrun_file /home/danzin/projects/jit_cpython/Python/pythonrun.c:1300:15
    #12 0x5d177a6e1452 in _PyRun_SimpleFileObject /home/danzin/projects/jit_cpython/Python/pythonrun.c:521:13
    #13 0x5d177a6e07cd in _PyRun_AnyFileObject /home/danzin/projects/jit_cpython/Python/pythonrun.c:81:15
    #14 0x5d177a75c88a in pymain_run_file_obj /home/danzin/projects/jit_cpython/Modules/main.c:410:15
    #15 0x5d177a75c88a in pymain_run_file /home/danzin/projects/jit_cpython/Modules/main.c:429:15
    #16 0x5d177a75a953 in pymain_run_python /home/danzin/projects/jit_cpython/Modules/main.c:691:21
    #17 0x5d177a75a953 in Py_RunMain /home/danzin/projects/jit_cpython/Modules/main.c:772:5
    #18 0x5d177a75b856 in pymain_main /home/danzin/projects/jit_cpython/Modules/main.c:802:12
    #19 0x5d177a75b9c7 in Py_BytesMain /home/danzin/projects/jit_cpython/Modules/main.c:826:12
    #20 0x781b68a2a574 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #21 0x781b68a2a627 in __libc_start_main csu/../csu/libc-start.c:360:3
    #22 0x5d1779aae4f4 in _start (/home/danzin/projects/jit_cpython/python+0x2db4f4) (BuildId: ebe22eb974668bb666c0824efbff0350de9b0c99)

0x5d177abfc290 is located 444 bytes after global variable '_PyUop_Flags' defined in '/home/danzin/projects/jit_cpython/./Include/internal/pycore_uop_metadata.h:37' (0x5d177abfb820) of size 2228
SUMMARY: AddressSanitizer: global-buffer-overflow /home/danzin/projects/jit_cpython/Python/optimizer.c:359:9 in _PyUOpPrint
Shadow bytes around the buggy address:
  0x5d177abfc000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x5d177abfc080: 00 00 00 00 00 00 00 00 00 00 04 f9 f9 f9 f9 f9
  0x5d177abfc100: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x5d177abfc180: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x5d177abfc200: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
=>0x5d177abfc280: f9 f9[f9]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x5d177abfc300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x5d177abfc380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x5d177abfc400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x5d177abfc480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x5d177abfc500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==75165==ABORTING

The interpreter was built with:

CC=clang-21 ./configure --enable-experimental-jit --with-pydebug --with-address-sanitizer --without-pymalloc

This was found when trying to run the fuzzer and breaks fuzzing, which depends on those debug messages.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

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

Python 3.15.0a2+ (tags/v3.15.0a2-262-g469f191a850:469f191a850, Dec 12 2025, 08:50:24) [Clang 21.1.2 (2ubuntu6)]

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)topic-JITtype-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