Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

array:*_setitem functions & co may crash on re-entrant__index__ #142555

Closed
Labels
extension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump
@jackfromeast

Description

@jackfromeast

What happened?

A user-defined__index__ can clear/shrink the targetarray during index conversion. The bounds check happens before the callback, but the write inb_setitem happens after, using a stale buffer and causing a write into freed/zero-length memory.

Proof of Concept:

importarrayvictim=array.array('b', [0]*64)classEvil:def__index__(self):# Re-entrant mutation: shrink the array while __setitem__ still holds# a pointer to the pre-clear buffer.victim.clear()return0victim[1]=Evil()

Affected Versions:

Details
Python VersionStatusExit Code
Python 3.9.24+ (heads/3.9:9c4638d, Oct 17 2025, 11:19:30)Exception1
Python 3.10.19+ (heads/3.10:0142619, Oct 17 2025, 11:20:05) [GCC 13.3.0]Exception1
Python 3.11.14+ (heads/3.11:88f3f5b, Oct 17 2025, 11:20:44) [GCC 13.3.0]Exception1
Python 3.12.12+ (heads/3.12:8cb2092, Oct 17 2025, 11:21:35) [GCC 13.3.0]Exception1
Python 3.13.9+ (heads/3.13:0760a57, Oct 17 2025, 11:22:25) [GCC 13.3.0]ASAN1
Python 3.14.0+ (heads/3.14:889e918, Oct 17 2025, 11:23:02) [GCC 13.3.0]ASAN1
Python 3.15.0a1+ (heads/main:fbf0843, Oct 17 2025, 11:23:37) [GCC 13.3.0]ASAN1

Vulnerable Code Snippet

Details
intPyObject_SetItem(PyObject*o,PyObject*key,PyObject*value){if (o==NULL||key==NULL||value==NULL) {null_error();return-1;    }PyMappingMethods*m=Py_TYPE(o)->tp_as_mapping;if (m&&m->mp_ass_subscript) {intres=m->mp_ass_subscript(o,key,value);assert(_Py_CheckSlotResult(o,"__setitem__",res >=0));returnres;    }if (Py_TYPE(o)->tp_as_sequence) {if (_PyIndex_Check(key)) {Py_ssize_tkey_value;key_value=PyNumber_AsSsize_t(key,PyExc_IndexError);if (key_value==-1&&PyErr_Occurred())return-1;returnPySequence_SetItem(o,key_value,value);        }elseif (Py_TYPE(o)->tp_as_sequence->sq_ass_item) {type_error("sequence index must be ""integer, not '%.200s'",key);return-1;        }    }type_error("'%.200s' object does not support item assignment",o);return-1;}staticintarray_ass_subscr(PyObject*op,PyObject*item,PyObject*value){Py_ssize_tstart,stop,step,slicelength,needed;arrayobject*self=arrayobject_CAST(op);array_state*state=find_array_state_by_type(Py_TYPE(self));arrayobject*other;intitemsize;if (PyIndex_Check(item)) {Py_ssize_ti=PyNumber_AsSsize_t(item,PyExc_IndexError);if (i==-1&&PyErr_Occurred())return-1;if (i<0)i+=Py_SIZE(self);if (i<0||i >=Py_SIZE(self)) {PyErr_SetString(PyExc_IndexError,"array assignment index out of range");return-1;        }if (value==NULL) {/* Fall through to slice assignment */start=i;stop=i+1;step=1;slicelength=1;        }else// Bug: SetItem happensreturn (*self->ob_descr->setitem)(self,i,value);    }   ...}staticintb_setitem(arrayobject*ap,Py_ssize_ti,PyObject*v){shortx;// Bug: Value's __index__ method has been called where the array buffer has been freed./* PyArg_Parse's 'b' formatter is for an unsigned char, therefore       must use the next size up that is signed ('h') and manually do       the overflow checking */if (!PyArg_Parse(v,"h;array item must be integer",&x))return-1;elseif (x<-128) {PyErr_SetString(PyExc_OverflowError,"signed char is less than minimum");return-1;    }elseif (x>127) {PyErr_SetString(PyExc_OverflowError,"signed char is greater than maximum");return-1;    }if (i >=0)// Freed buffer has been visited.        ((char*)ap->ob_item)[i]= (char)x;return0;}

Sanitizer

Details
===================================================================1453430==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x7aef85b7e366 bp 0x7ffc096c5ca0 sp 0x7ffc096c5c00 T0)==1453430==The signal is caused by a WRITE memory access.==1453430==Hint: address points to the zero page.    #0 0x7aef85b7e366 in b_setitem Modules/arraymodule.c:235    #1 0x7aef85b8155a in array_ass_subscr Modules/arraymodule.c:2528    #2 0x61f8093f2be7 in PyObject_SetItem Objects/abstract.c:237    #3 0x61f8096de2f6 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:11245    #4 0x61f8096e4e54 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121    #5 0x61f8096e5148 in _PyEval_Vector Python/ceval.c:2001    #6 0x61f8096e53f8 in PyEval_EvalCode Python/ceval.c:884    #7 0x61f8097dc507 in run_eval_code_obj Python/pythonrun.c:1365    #8 0x61f8097dc723 in run_mod Python/pythonrun.c:1459    #9 0x61f8097dd57a in pyrun_file Python/pythonrun.c:1293    #10 0x61f8097e0220 in _PyRun_SimpleFileObject Python/pythonrun.c:521    #11 0x61f8097e04f6 in _PyRun_AnyFileObject Python/pythonrun.c:81    #12 0x61f80983174d in pymain_run_file_obj Modules/main.c:410    #13 0x61f8098319b4 in pymain_run_file Modules/main.c:429    #14 0x61f8098331b2 in pymain_run_python Modules/main.c:691    #15 0x61f809833842 in Py_RunMain Modules/main.c:772    #16 0x61f809833a2e in pymain_main Modules/main.c:802    #17 0x61f809833db3 in Py_BytesMain Modules/main.c:826    #18 0x61f8092b7645 in main Programs/python.c:15    #19 0x7aef8642a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58    #20 0x7aef8642a28a in __libc_start_main_impl ../csu/libc-start.c:360    #21 0x61f8092b7574 in _start (/home/jackfromeast/Desktop/entropy/tasks/grammar-afl++-latest/targets/cpython/python+0x2dd574) (BuildId: ff3dc40ea460bd4beb2c3a72283cca525b319bf0)AddressSanitizer can not provide additional info.SUMMARY: AddressSanitizer: SEGV Modules/arraymodule.c:235 in b_setitem==1453430==ABORTING

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-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


      [8]ページ先頭

      ©2009-2026 Movatter.jp