Skip to content

SEGV on _Py_type_getattro_impl #135637

Closed as not planned
Closed as not planned
@haruki3hhh

Description

@haruki3hhh

Crash report

What happened?

import ast
import ctypes
import sys
import struct

class AdvancedCorruption:
  
    def __init__(self):
        self.original_obj = None
        self.corrupted = False
    
    def create_corrupted_sequence(self):
        seq = ["field1", "field2", "field3"]
        self.original_obj = seq
        
        self.corrupt_sequence_memory(seq)
        
        return seq
    
    def corrupt_sequence_memory(self, seq):
        obj_addr = id(seq)
        
        ptr_size = ctypes.sizeof(ctypes.c_void_p)
        
        invalid_ptr = 0x4141414141414141  # "AAAAAAAA"
        ctypes.memmove(obj_addr, ctypes.byref(ctypes.c_void_p(invalid_ptr)), ptr_size)
        
        corrupted_refcount = 0x4242424242424242  # "BBBBBBBB"
        ctypes.memmove(obj_addr + ptr_size, ctypes.byref(ctypes.c_void_p(corrupted_refcount)), ptr_size)
    
    def create_delayed_corruption(self):
        class DelayedCorruption:
            def __init__(self, parent):
                self.parent = parent
                self.data = ["field1", "field2"]
                self.corrupted = False
            
            def __contains__(self, item):
                if not self.corrupted:
                    self.parent.corrupt_sequence_memory(self)
                    self.corrupted = True
                return item in self.data
            
            def __iter__(self):
                if not self.corrupted:
                    self.parent.corrupt_sequence_memory(self)
                    self.corrupted = True
                return iter(self.data)
        
        return DelayedCorruption(self)

corruption = AdvancedCorruption()

print( Immediate memory corruption")
corrupted_seq = corruption.create_corrupted_sequence()
ast.AST._fields = corrupted_seq

try:
    t = ast.AST(arg1=123)
    print("Unexpected: No crash occurred")
except Exception as e:
    print(f"Expected crash: {e}")

print("\nDelayed corruption on access")
delayed_corrupted = corruption.create_delayed_corruption()
ast.AST._fields = delayed_corrupted

try:
    t = ast.AST(arg1=123)
    print("Unexpected: No crash occurred")
except Exception as e:
    print(f"Expected crash: {e}")

Compile Script

#!/bin/bash -eu
./configure --with-address-sanitizer --without-pymalloc
ASAN_OPTIONS=detect_leaks=0 make -j$(nproc)
test -f python

ASAN Report

Method 1: Immediate memory corruption
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3402256==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x555555a40b11 bp 0x7fffffffc8a0 sp 0x7fffffffc7c0 T0)
==3402256==The signal is caused by a READ memory access.
==3402256==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
    #0 0x555555a40b11 in _Py_type_getattro_impl Objects/typeobject.c:6314
    #1 0x555555a40b11 in _Py_type_getattro Objects/typeobject.c:6363
    #2 0x555555980a87 in PyObject_GetAttr Objects/object.c:1300
    #3 0x555555b364c5 in ast_type_init Python/Python-ast.c:5172
    #4 0x5555559fe297 in type_call Objects/typeobject.c:2426
    #5 0x555555861f2d in _PyObject_MakeTpCall Objects/call.c:242
    #6 0x55555570bdf2 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:2977
    #7 0x555555bd47d6 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:119
    #8 0x555555bd47d6 in _PyEval_Vector Python/ceval.c:1975
    #9 0x555555bd47d6 in PyEval_EvalCode Python/ceval.c:866
    #10 0x555555d1a00e in run_eval_code_obj Python/pythonrun.c:1365
    #11 0x555555d1a00e in run_mod Python/pythonrun.c:1436
    #12 0x555555d1eb87 in pyrun_file Python/pythonrun.c:1293
    #13 0x555555d1eb87 in _PyRun_SimpleFileObject Python/pythonrun.c:521
    #14 0x555555d1f6ac in _PyRun_AnyFileObject Python/pythonrun.c:81
    #15 0x555555d9bc2c in pymain_run_file_obj Modules/main.c:410
    #16 0x555555d9bc2c in pymain_run_file Modules/main.c:429
    #17 0x555555d9bc2c in pymain_run_python Modules/main.c:691
    #18 0x555555d9d50e in Py_RunMain Modules/main.c:772
    #19 0x555555d9d50e in pymain_main Modules/main.c:802
    #20 0x555555d9d50e in Py_BytesMain Modules/main.c:826
    #21 0x7ffff76101c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #22 0x7ffff761028a in __libc_start_main_impl ../csu/libc-start.c:360
    #23 0x555555740064 in _start (/workspaces/get_trace/ColdPatch/vuln/cpython/py-pr-126105/latest-cpython/python+0x1ec064) (BuildId: 116b37c120204afd1f0e685e4399db097a1a0823)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV Objects/typeobject.c:6314 in _Py_type_getattro_impl
==3402256==ABORTING

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

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

Python 3.15.0a0 (heads/main:7c685894cd9, Jun 17 2025, 03:14:54) [GCC 13.3.0]

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-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