Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork34k
Closed
Description
What happened?
A crafted__index__ invoked byroot[bad_index:] clears the element soelement_ass_subscr freesself->extra, but the slice handling continues and callsPySlice_AdjustIndices on the dangling child store, dereferencing NULL and crashing the interpreter.
Proof of Concept:
importxml.etree.ElementTreeasETroot=ET.Element("root")root.extend([ET.Element("c0"),ET.Element("c1")])classEvil:def__index__(self):# Re-entrant mutation: clear() frees the internal child storageglobalrootroot.clear()return0bad_index=Evil()root[bad_index:]
Affected Versions
| Python Version | Status | Exit Code |
|---|---|---|
Python 3.9.24+ (heads/3.9:111bbc15b26, Oct 27 2025, 21:34:13) | OK | 0 |
Python 3.10.19+ (heads/3.10:014261980b1, Oct 27 2025, 21:19:00) [Clang 18.1.3 (1ubuntu1)] | ASAN | 1 |
Python 3.11.14+ (heads/3.11:88f3f5b5f11, Oct 27 2025, 21:20:35) [Clang 18.1.3 (1ubuntu1)] | ASAN | 1 |
Python 3.12.12+ (heads/3.12:8cb2092bd8c, Oct 27 2025, 21:27:07) [Clang 18.1.3 (1ubuntu1)] | ASAN | 1 |
Python 3.13.9+ (heads/3.13:9c8eade20c6, Oct 27 2025, 21:28:49) [Clang 18.1.3 (1ubuntu1)] | ASAN | 1 |
Python 3.14.0+ (heads/3.14:2e216728038, Oct 27 2025, 21:30:55) [Clang 18.1.3 (1ubuntu1)] | ASAN | 1 |
Python 3.15.0a1+ (heads/main:f5394c257ce, Oct 27 2025, 21:32:37) [Clang 18.1.3 (1ubuntu1)] | ASAN | 1 |
Vulnerable Code
staticPyObject*element_subscr(PyObject*op,PyObject*item){ElementObject*self=_Element_CAST(op);if (PyIndex_Check(item)) {Py_ssize_ti=PyNumber_AsSsize_t(item,PyExc_IndexError);if (i==-1&&PyErr_Occurred()) {returnNULL; }if (i<0&&self->extra)i+=self->extra->length;returnelement_getitem(op,i); }elseif (PySlice_Check(item)) {Py_ssize_tstart,stop,step,slicelen,i;size_tcur;PyObject*list;if (!self->extra)returnPyList_New(0);/* Call _PyEval_SliceIndex -> _PyNumber_Index and reentrant to the interpreter again. */if (PySlice_Unpack(item,&start,&stop,&step)<0) {returnNULL; }/* ... */// Crash: self->extra is a null pointer nowslicelen=PySlice_AdjustIndices(self->extra->length,&start,&stop,step);}
Sanitizer Output
AddressSanitizer:DEADLYSIGNAL===================================================================11783==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7638bd19b2a1 bp 0x7ffd815de790 sp 0x7ffd815de690 T0)==11783==The signal is caused by a READ memory access.==11783==Hint: address points to the zero page. #0 0x7638bd19b2a1 in element_subscr Modules/_elementtree.c:1819 #1 0x7638bd19b2a1 in element_subscr Modules/_elementtree.c:1794 #2 0x5f64666f687c in PyObject_GetItem Objects/abstract.c:163 #3 0x5f64665ec668 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1143 #4 0x5f6466ac4ad6 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121 #5 0x5f6466ac4ad6 in _PyEval_Vector Python/ceval.c:2001 #6 0x5f6466ac4ad6 in PyEval_EvalCode Python/ceval.c:884 #7 0x5f6466c0a16e in run_eval_code_obj Python/pythonrun.c:1365 #8 0x5f6466c0a16e in run_mod Python/pythonrun.c:1459 #9 0x5f6466c0ee17 in pyrun_file Python/pythonrun.c:1293 #10 0x5f6466c0ee17 in _PyRun_SimpleFileObject Python/pythonrun.c:521 #11 0x5f6466c0f93c in _PyRun_AnyFileObject Python/pythonrun.c:81 #12 0x5f6466c82e3c in pymain_run_file_obj Modules/main.c:410 #13 0x5f6466c82e3c in pymain_run_file Modules/main.c:429 #14 0x5f6466c82e3c in pymain_run_python Modules/main.c:691 #15 0x5f6466c8471e in Py_RunMain Modules/main.c:772 #16 0x5f6466c8471e in pymain_main Modules/main.c:802 #17 0x5f6466c8471e in Py_BytesMain Modules/main.c:826 #18 0x7638bde2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #19 0x7638bde2a28a in __libc_start_main_impl ../csu/libc-start.c:360 #20 0x5f646661e634 in _start (/home/jackfromeast/Desktop/entropy/targets/grammar-afl++-latest/targets/cpython/python+0x206634) (BuildId: 4d105290d0ad566a4d6f4f7b2f05fbc9e317b533)AddressSanitizer can not provide additional info.SUMMARY: AddressSanitizer: SEGV Modules/_elementtree.c:1819 in element_subscr==11783==ABORTING[Inferior 1 (process 11783) exited with code 01]Linked PRs
- gh-143200: fix UAFs in
Element.__{set,get}item__when the element is concurrently mutated #143226 - [3.14] gh-143200: fix UAFs in
Element.__{set,get}item__when the element is concurrently mutated (GH-143226) #143273 - [3.13] gh-143200: fix UAFs in
Element.__{set,get}item__when the element is concurrently mutated (GH-143226) #143274