-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Open
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Description
What happened?
memory_subscript() creates a new view (mbuf_add_view) before parsing slice indices. If a slice bound’s __index__ releases/truncates the underlying buffer (e.g., mv.release(); ftruncate()), the newly created subview keeps a dangling pointer. Subsequent access (e.g., sub[0]) dereferences freed/invalid memory, crashing in unpack_single.
Proof of Concept:
import mmap, os, tempfile
fd, path = tempfile.mkstemp()
os.write(fd, b"A" * 4096)
mm = mmap.mmap(fd, 4096, access=mmap.ACCESS_WRITE)
mv = memoryview(mm)
class Trigger:
def __index__(self):
mv.release()
os.ftruncate(fd, 0)
return 0
try:
sub = mv[slice(Trigger(), None, None)]
sub[0] # Trigger the slicing to call __index__
finally:
mm.close()
os.close(fd)
os.unlink(path)Related Code Snippet
static PyObject *
memory_subscript(PyObject *_self, PyObject *key)
{
PyMemoryViewObject *self = (PyMemoryViewObject *)_self;
Py_buffer *view;
view = &(self->view);
CHECK_RELEASED(self);
if (view->ndim == 0) {
if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
const char *fmt = adjust_fmt(view);
if (fmt == NULL)
return NULL;
return unpack_single(self, view->buf, fmt);
}
else if (key == Py_Ellipsis) {
return Py_NewRef(self);
}
else {
PyErr_SetString(PyExc_TypeError,
"invalid indexing of 0-dim memory");
return NULL;
}
}
if (_PyIndex_Check(key)) {
Py_ssize_t index;
index = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (index == -1 && PyErr_Occurred())
return NULL;
return memory_item((PyObject *)self, index);
}
else if (PySlice_Check(key)) {
CHECK_RESTRICTED(self);
PyMemoryViewObject *sliced;
sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
if (sliced == NULL)
return NULL;
// Call __index__ method which close the mmap memory while sliced still holds its pointer
if (init_slice(&sliced->view, key, 0) < 0) {
Py_DECREF(sliced);
return NULL;
}
init_len(&sliced->view);
init_flags(sliced);
return (PyObject *)sliced;
}
else if (is_multiindex(key)) {
return memory_item_multi(self, key);
}
else if (is_multislice(key)) {
PyErr_SetString(PyExc_NotImplementedError,
"multi-dimensional slicing is not implemented");
return NULL;
}
PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
return NULL;
}
Affected Versions:
| Python Version | Status | Exit Code |
|---|---|---|
Python 3.9.24+ (heads/3.9:9c4638d, Oct 17 2025, 11:19:30) |
ASAN | 1 |
Python 3.10.19+ (heads/3.10:0142619, Oct 17 2025, 11:20:05) [GCC 13.3.0] |
ASAN | 1 |
Python 3.11.14+ (heads/3.11:88f3f5b, Oct 17 2025, 11:20:44) [GCC 13.3.0] |
ASAN | 1 |
Python 3.12.12+ (heads/3.12:8cb2092, Oct 17 2025, 11:21:35) [GCC 13.3.0] |
ASAN | 1 |
Python 3.13.9+ (heads/3.13:0760a57, Oct 17 2025, 11:22:25) [GCC 13.3.0] |
ASAN | 1 |
Python 3.14.0+ (heads/3.14:889e918, Oct 17 2025, 11:23:02) [GCC 13.3.0] |
ASAN | 1 |
Python 3.15.0a1+ (heads/main:fbf0843, Oct 17 2025, 11:23:37) [GCC 13.3.0] |
ASAN | 1 |
Sanitizer Output
=================================================================
==1532703==ERROR: AddressSanitizer: BUS on unknown address (pc 0x5ae17c7bd8ce bp 0x7fffb3a81570 sp 0x7fffb3a814b0 T0)
==1532703==The signal is caused by a READ memory access.
==1532703==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 0x5ae17c7bd8ce in unpack_single Objects/memoryobject.c:1842
#1 0x5ae17c7be2c2 in memory_item Objects/memoryobject.c:2474
#2 0x5ae17c7c31d6 in memory_subscript Objects/memoryobject.c:2610
#3 0x5ae17c6e5393 in PyObject_GetItem Objects/abstract.c:163
#4 0x5ae17c98a8f8 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:62
#5 0x5ae17c9d7e54 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121
#6 0x5ae17c9d8148 in _PyEval_Vector Python/ceval.c:2001
#7 0x5ae17c9d83f8 in PyEval_EvalCode Python/ceval.c:884
#8 0x5ae17cacf507 in run_eval_code_obj Python/pythonrun.c:1365
#9 0x5ae17cacf723 in run_mod Python/pythonrun.c:1459
#10 0x5ae17cad057a in pyrun_file Python/pythonrun.c:1293
#11 0x5ae17cad3220 in _PyRun_SimpleFileObject Python/pythonrun.c:521
#12 0x5ae17cad34f6 in _PyRun_AnyFileObject Python/pythonrun.c:81
#13 0x5ae17cb2474d in pymain_run_file_obj Modules/main.c:410
#14 0x5ae17cb249b4 in pymain_run_file Modules/main.c:429
#15 0x5ae17cb261b2 in pymain_run_python Modules/main.c:691
#16 0x5ae17cb26842 in Py_RunMain Modules/main.c:772
#17 0x5ae17cb26a2e in pymain_main Modules/main.c:802
#18 0x5ae17cb26db3 in Py_BytesMain Modules/main.c:826
#19 0x5ae17c5aa645 in main Programs/python.c:15
#20 0x715a34c2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#21 0x715a34c2a28a in __libc_start_main_impl ../csu/libc-start.c:360
#22 0x5ae17c5aa574 in _start (/home/jackfromeast/Desktop/entropy/tasks/grammar-afl++-latest/targets/cpython/python+0x2dd574) (BuildId: ff3dc40ea460bd4beb2c3a72283cca525b319bf0)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: BUS Objects/memoryobject.c:1842 in unpack_single
==1532703==ABORTINGMetadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump