-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Open
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtopic-ctypestype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Description
What happened?
Swapping a ctypes array instance to a wider subclass through __class__ bypasses the length check in Array_ass_item_lock_held, so writing to the new tail positions stores past the original allocation and corrupts adjacent heap memory.
Proof of Concept:
from ctypes import c_long
Base = c_long * 3
Wide = c_long * 5
victim = Base(1, 2, 3)
victim.__class__ = Wide # Make the CPython think we have a array whose length is 5.
victim[4] = 42 # OOB writeAffected Versions:
Details
| Python Version | Status | Exit Code |
|---|---|---|
Python 3.9.24+ (heads/3.9:111bbc15b26, Oct 27 2025, 21:34:13) |
ASAN | 1 |
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:
Details
static int
Array_ass_item_lock_held(PyObject *myself, Py_ssize_t index, PyObject *value)
{
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(myself);
CDataObject *self = _CDataObject_CAST(myself);
Py_ssize_t size, offset;
char *ptr;
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
"Array does not support item deletion");
return -1;
}
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return -1;
}
assert(stginfo); /* Cannot be NULL for array object instances */
if (index < 0 || index >= stginfo->length) {
PyErr_SetString(PyExc_IndexError,
"invalid index");
return -1;
}
size = stginfo->size / stginfo->length;
offset = index * size;
ptr = self->b_ptr + offset;
return PyCData_set(st, myself, stginfo->proto, stginfo->setfunc, value,
index, size, ptr);
}Sanitizer Output:
Details
=================================================================
==1353195==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50300001fa10 at pc 0x7d86b13e09a7 bp 0x7ffdb7d72a30 sp 0x7ffdb7d72a28
WRITE of size 8 at 0x50300001fa10 thread T0
#0 0x7d86b13e09a6 in i64_set /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/cfield.c:644:1
#1 0x7d86b13cb6ff in PyCData_set /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/_ctypes.c:3542:14
#2 0x7d86b13cb6ff in Array_ass_item_lock_held /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/_ctypes.c:5194:12
#3 0x7d86b13caf37 in Array_ass_subscript_lock_held /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/_ctypes.c:5227:16
#4 0x7d86b13caf37 in Array_ass_subscript /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/_ctypes.c:5271:14
#5 0x57424f119d68 in _PyEval_EvalFrameDefault /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/generated_cases.c.h:11245:27
#6 0x57424f10b3bb in _PyEval_EvalFrame /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Include/internal/pycore_ceval.h:121:16
#7 0x57424f10b3bb in _PyEval_Vector /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/ceval.c:2005:12
#8 0x57424f10b3bb in PyEval_EvalCode /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/ceval.c:888:21
#9 0x57424f262370 in run_eval_code_obj /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:1365:12
#10 0x57424f262370 in run_mod /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:1459:19
#11 0x57424f25c43c in pyrun_file /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:1293:15
#12 0x57424f25c43c in _PyRun_SimpleFileObject /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:521:13
#13 0x57424f25bb05 in _PyRun_AnyFileObject /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:81:15
#14 0x57424f2c3fe5 in pymain_run_file_obj /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:410:15
#15 0x57424f2c3fe5 in pymain_run_file /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:429:15
#16 0x57424f2c299d in pymain_run_python /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:691:21
#17 0x57424f2c299d in Py_RunMain /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:772:5
#18 0x57424f2c3451 in pymain_main /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:802:12
#19 0x57424f2c35c3 in Py_BytesMain /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:826:12
#20 0x7d86b1c2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#21 0x7d86b1c2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#22 0x57424ec73104 in _start (/home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/python+0x1c7104) (BuildId: 5de9d2fcbcd44bfc1b0fe256566d49ad35ca1d56)
0x50300001fa10 is located 8 bytes after 24-byte region [0x50300001f9f0,0x50300001fa08)
allocated by thread T0 here:
#0 0x57424ed0df53 in malloc (/home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/python+0x261f53) (BuildId: 5de9d2fcbcd44bfc1b0fe256566d49ad35ca1d56)
#1 0x7d86b13bdad2 in PyCData_MallocBuffer /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/_ctypes.c:3271:30
#2 0x7d86b13bdad2 in generic_pycdata_new /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/_ctypes.c:3589:15
#3 0x57424ef91a9b in type_call /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Objects/typeobject.c:2449:11
#4 0x57424ee427b2 in _PyObject_MakeTpCall /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Objects/call.c:242:18
#5 0x57424f12a837 in _PyEval_EvalFrameDefault /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/generated_cases.c.h:1620:35
#6 0x57424f10b3bb in _PyEval_EvalFrame /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Include/internal/pycore_ceval.h:121:16
#7 0x57424f10b3bb in _PyEval_Vector /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/ceval.c:2005:12
#8 0x57424f10b3bb in PyEval_EvalCode /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/ceval.c:888:21
#9 0x57424f262370 in run_eval_code_obj /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:1365:12
#10 0x57424f262370 in run_mod /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:1459:19
#11 0x57424f25c43c in pyrun_file /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:1293:15
#12 0x57424f25c43c in _PyRun_SimpleFileObject /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:521:13
#13 0x57424f25bb05 in _PyRun_AnyFileObject /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Python/pythonrun.c:81:15
#14 0x57424f2c3fe5 in pymain_run_file_obj /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:410:15
#15 0x57424f2c3fe5 in pymain_run_file /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:429:15
#16 0x57424f2c299d in pymain_run_python /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:691:21
#17 0x57424f2c299d in Py_RunMain /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:772:5
#18 0x57424f2c3451 in pymain_main /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:802:12
#19 0x57424f2c35c3 in Py_BytesMain /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/Modules/main.c:826:12
#20 0x7d86b1c2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#21 0x7d86b1c2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#22 0x57424ec73104 in _start (/home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/python+0x1c7104) (BuildId: 5de9d2fcbcd44bfc1b0fe256566d49ad35ca1d56)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/jackfromeast/Desktop/entropy/tasks/reproducexx/targets/cpython-main/./Modules/_ctypes/cfield.c:644:1 in i64_set
Shadow bytes around the buggy address:
0x50300001f780: 00 00 00 00 fa fa fd fd fd fd fa fa 00 00 00 00
0x50300001f800: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
0x50300001f880: 00 00 fa fa fd fd fd fd fa fa 00 00 00 00 fa fa
0x50300001f900: fd fd fd fd fa fa fd fd fd fd fa fa 00 00 00 00
0x50300001f980: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00
=>0x50300001fa00: 00 fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300001fa80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300001fb00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300001fb80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300001fc00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300001fc80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==1353195==ABORTING
superboy-zjc and yihong0618
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtopic-ctypestype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump