Skip to content

uaf in _elementtree Element.iter(tag) #158032

Description

@djarfluka

Bug report

Bug description:

import xml.etree.ElementTree as ET
assert ET.Element.__module__ in ('xml.etree.ElementTree',)
import _elementtree

class Tag:
    def __eq__(self, other):
        child.tag = "replaced"      # drops the last reference to this Tag
        return NotImplemented
    __hash__ = object.__hash__

class Sought:
    def __eq__(self, other):
        print("reflected got", type(other))
        return NotImplemented

root = _elementtree.Element("root")
child = _elementtree.SubElement(root, "x")
child.tag = Tag()
print(list(root.iter(Sought())))

asan output:

=================================================================
==55==ERROR: AddressSanitizer: heap-use-after-free on address 0x513000051d60 at pc 0xaaaabe278154 bp 0xffffffc8e040 sp 0xffffffc8e030
READ of size 4 at 0x513000051d60 thread T0
    #0 0xaaaabe278150 in _Py_IsImmortal Include/refcount.h:132
    #1 0xaaaabe278150 in _PyStackRef_FromPyObjectNew Include/internal/pycore_stackref.h:602
    #2 0xaaaabe278150 in _PyEval_Vector Python/ceval.c:2158
    #3 0xaaaabdfc8c24 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:144
    #4 0xaaaabdfc8c24 in vectorcall_unbound Objects/typeobject.c:3032
    #5 0xaaaabdfc8c24 in maybe_call_special_one_arg Objects/typeobject.c:3174
    #6 0xaaaabdfc8c24 in _PyObject_MaybeCallSpecialOneArg Objects/typeobject.c:3189
    #7 0xaaaabdfc8c24 in slot_tp_richcompare Objects/typeobject.c:11012
    #8 0xaaaabde6ae40 in do_richcompare Objects/object.c:1071
    #9 0xaaaabde6ae40 in PyObject_RichCompare Objects/object.c:1114
    #10 0xaaaabde70b54 in PyObject_RichCompareBool Objects/object.c:1136
    #11 0xffffaf9ccef0 in elementiter_next Modules/_elementtree.c:2384
    #12 0xaaaabdd778fc in list_extend_iter_lock_held Objects/listobject.c:1318
    #13 0xaaaabdd778fc in _list_extend Objects/listobject.c:1507
    #14 0xaaaabdd78b6c in list___init___impl Objects/listobject.c:3542
    #15 0xaaaabdd78b6c in list_vectorcall Objects/listobject.c:3566
    #16 0xaaaabdc772d0 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:144
    #17 0xaaaabdc772d0 in PyObject_Vectorcall Objects/call.c:327
    #18 0xaaaabe258248 in _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:770
    #19 0xaaaabd9dd368 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1906
    #20 0xaaaabe27719c in _PyEval_EvalFrame Include/internal/pycore_ceval.h:122
    #21 0xaaaabe27719c in _PyEval_Vector Python/ceval.c:2176
    #22 0xaaaabe27719c in PyEval_EvalCode Python/ceval.c:681
    #23 0xaaaabe477ac4 in run_mod Python/pythonrun.c:1509
    #24 0xaaaabe478948 in _PyRun_File Python/pythonrun.c:1332
    #25 0xaaaabe47cc0c in _PyRun_SimpleFile Python/pythonrun.c:544
    #26 0xaaaabe4809e0 in _PyRun_AnyFile Python/pythonrun.c:92
    #27 0xaaaabe54bd8c in pymain_run_file_obj Modules/main.c:478
    #28 0xaaaabe54bd8c in pymain_run_file Modules/main.c:494
    #29 0xaaaabe54bd8c in pymain_run_python Modules/main.c:804
    #30 0xaaaabe54bd8c in Py_RunMain Modules/main.c:891
    #31 0xaaaabe54e0b8 in pymain_main Modules/main.c:921
    #32 0xaaaabe54e0b8 in Py_BytesMain Modules/main.c:945
    #33 0xffffb2bf84c0  (/lib/aarch64-linux-gnu/libc.so.6+0x284c0) (BuildId: 27027b96e5b8c475fc327aa445bea1c71d37b4e2)
    #34 0xffffb2bf8594 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x28594) (BuildId: 27027b96e5b8c475fc327aa445bea1c71d37b4e2)
    #35 0xaaaabda4746c in _start (/src/cpython/python+0x17a746c) (BuildId: fa8e9c5023d067471f9646ceca1b9bc57d6cd116)

0x513000051d60 is located 32 bytes inside of 328-byte region [0x513000051d40,0x513000051e88)
freed by thread T0 here:
    #0 0xffffb35961b4 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0xaaaabdf428ec in subtype_dealloc Objects/typeobject.c:2846
    #2 0xaaaabde69a20 in _Py_Dealloc Objects/object.c:3346
    #3 0xaaaabe35bd8c in Py_DECREF_MORTAL Include/internal/pycore_object.h:449
    #4 0xaaaabe35bd8c in PyStackRef_XCLOSE Include/internal/pycore_stackref.h:726
    #5 0xaaaabe35bd8c in _PyFrame_ClearLocals Python/frame.c:108
    #6 0xaaaabe35c8e0 in _PyFrame_ClearExceptCode Python/frame.c:133
    #7 0xaaaabe25a4e4 in clear_thread_frame Python/ceval.c:1987
    #8 0xaaaabe25a4e4 in _PyEval_FrameClearAndPop Python/ceval.c:2019
    #9 0xaaaabd9e1914 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:11557
    #10 0xaaaabe278080 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:122
    #11 0xaaaabe278080 in _PyEval_Vector Python/ceval.c:2176
    #12 0xaaaabdfc8c24 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:144
    #13 0xaaaabdfc8c24 in vectorcall_unbound Objects/typeobject.c:3032
    #14 0xaaaabdfc8c24 in maybe_call_special_one_arg Objects/typeobject.c:3174
    #15 0xaaaabdfc8c24 in _PyObject_MaybeCallSpecialOneArg Objects/typeobject.c:3189
    #16 0xaaaabdfc8c24 in slot_tp_richcompare Objects/typeobject.c:11012
    #17 0xaaaabde6ab14 in do_richcompare Objects/object.c:1065
    #18 0xaaaabde6ab14 in PyObject_RichCompare Objects/object.c:1114
    #19 0xaaaabde70b54 in PyObject_RichCompareBool Objects/object.c:1136
    #20 0xffffaf9ccef0 in elementiter_next Modules/_elementtree.c:2384
    #21 0xaaaabdd778fc in list_extend_iter_lock_held Objects/listobject.c:1318
    #22 0xaaaabdd778fc in _list_extend Objects/listobject.c:1507
    #23 0xaaaabdd78b6c in list___init___impl Objects/listobject.c:3542
    #24 0xaaaabdd78b6c in list_vectorcall Objects/listobject.c:3566
    #25 0xaaaabdc772d0 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:144
    #26 0xaaaabdc772d0 in PyObject_Vectorcall Objects/call.c:327
    #27 0xaaaabe258248 in _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:770
    #28 0xaaaabd9dd368 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1906
    #29 0xaaaabe27719c in _PyEval_EvalFrame Include/internal/pycore_ceval.h:122
    #30 0xaaaabe27719c in _PyEval_Vector Python/ceval.c:2176
    #31 0xaaaabe27719c in PyEval_EvalCode Python/ceval.c:681
    #32 0xaaaabe477ac4 in run_mod Python/pythonrun.c:1509
    #33 0xaaaabe478948 in _PyRun_File Python/pythonrun.c:1332
    #34 0xaaaabe47cc0c in _PyRun_SimpleFile Python/pythonrun.c:544
    #35 0xaaaabe4809e0 in _PyRun_AnyFile Python/pythonrun.c:92
    #36 0xaaaabe54bd8c in pymain_run_file_obj Modules/main.c:478
    #37 0xaaaabe54bd8c in pymain_run_file Modules/main.c:494
    #38 0xaaaabe54bd8c in pymain_run_python Modules/main.c:804
    #39 0xaaaabe54bd8c in Py_RunMain Modules/main.c:891
    #40 0xaaaabe54e0b8 in pymain_main Modules/main.c:921
    #41 0xaaaabe54e0b8 in Py_BytesMain Modules/main.c:945
    #42 0xffffb2bf84c0  (/lib/aarch64-linux-gnu/libc.so.6+0x284c0) (BuildId: 27027b96e5b8c475fc327aa445bea1c71d37b4e2)
    #43 0xffffb2bf8594 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x28594) (BuildId: 27027b96e5b8c475fc327aa445bea1c71d37b4e2)
    #44 0xaaaabda4746c in _start (/src/cpython/python+0x17a746c) (BuildId: fa8e9c5023d067471f9646ceca1b9bc57d6cd116)

previously allocated by thread T0 here:
    #0 0xffffb35976d0 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0xaaaabdf82a1c in _PyObject_MallocWithType Include/internal/pycore_object_alloc.h:46
    #2 0xaaaabdf82a1c in _PyType_AllocNoTrack Objects/typeobject.c:2498
    #3 0xaaaabdf830a0 in PyType_GenericAlloc Objects/typeobject.c:2529
    #4 0xaaaabdf88aa8 in type_call Objects/typeobject.c:2442
    #5 0xaaaabdc75200 in _PyObject_MakeTpCall Objects/call.c:242
    #6 0xaaaabe258248 in _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:770
    #7 0xaaaabd9dd368 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1906
    #8 0xaaaabe27719c in _PyEval_EvalFrame Include/internal/pycore_ceval.h:122
    #9 0xaaaabe27719c in _PyEval_Vector Python/ceval.c:2176
    #10 0xaaaabe27719c in PyEval_EvalCode Python/ceval.c:681
    #11 0xaaaabe477ac4 in run_mod Python/pythonrun.c:1509
    #12 0xaaaabe478948 in _PyRun_File Python/pythonrun.c:1332
    #13 0xaaaabe47cc0c in _PyRun_SimpleFile Python/pythonrun.c:544
    #14 0xaaaabe4809e0 in _PyRun_AnyFile Python/pythonrun.c:92
    #15 0xaaaabe54bd8c in pymain_run_file_obj Modules/main.c:478
    #16 0xaaaabe54bd8c in pymain_run_file Modules/main.c:494
    #17 0xaaaabe54bd8c in pymain_run_python Modules/main.c:804
    #18 0xaaaabe54bd8c in Py_RunMain Modules/main.c:891
    #19 0xaaaabe54e0b8 in pymain_main Modules/main.c:921
    #20 0xaaaabe54e0b8 in Py_BytesMain Modules/main.c:945
    #21 0xffffb2bf84c0  (/lib/aarch64-linux-gnu/libc.so.6+0x284c0) (BuildId: 27027b96e5b8c475fc327aa445bea1c71d37b4e2)
    #22 0xffffb2bf8594 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x28594) (BuildId: 27027b96e5b8c475fc327aa445bea1c71d37b4e2)
    #23 0xaaaabda4746c in _start (/src/cpython/python+0x17a746c) (BuildId: fa8e9c5023d067471f9646ceca1b9bc57d6cd116)

SUMMARY: AddressSanitizer: heap-use-after-free Include/refcount.h:132 in _Py_IsImmortal
Shadow bytes around the buggy address:
  0x513000051a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x513000051b00: 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x513000051b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x513000051c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x513000051c80: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
=>0x513000051d00: fa fa fa fa fa fa fa fa fd fd fd fd[fd]fd fd fd
  0x513000051d80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x513000051e00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x513000051e80: fd fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x513000051f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x513000051f80: 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
==55==ABORTING
Aborted

CPython versions tested on:

CPython main branch

Operating systems tested on:

Other, Linux

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtopic-XMLtype-bugAn unexpected behavior, bug, or errortype-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