File tree 2 files changed +9
-6
lines changed
Misc/NEWS.d/next/Core and Builtins 2 files changed +9
-6
lines changed Original file line number Diff line number Diff line change
1
+ Fix a segmentation fault caused by a use-after-free bug in ``frame_dealloc ``
2
+ when the trashcan delays the deallocation of a ``PyFrameObject ``.
Original file line number Diff line number Diff line change @@ -851,20 +851,21 @@ frame_dealloc(PyFrameObject *f)
851
851
/* It is the responsibility of the owning generator/coroutine
852
852
* to have cleared the generator pointer */
853
853
854
- assert (f -> f_frame -> owner != FRAME_OWNED_BY_GENERATOR ||
855
- _PyFrame_GetGenerator (f -> f_frame )-> gi_frame_state == FRAME_CLEARED );
856
-
857
854
if (_PyObject_GC_IS_TRACKED (f )) {
858
855
_PyObject_GC_UNTRACK (f );
859
856
}
860
857
861
858
Py_TRASHCAN_BEGIN (f , frame_dealloc );
862
859
PyCodeObject * co = NULL ;
863
860
861
+ /* GH-106092: If f->f_frame was on the stack and we reached the maximum
862
+ * nesting depth for deallocations, the trashcan may have delayed this
863
+ * deallocation until after f->f_frame is freed. Avoid dereferencing
864
+ * f->f_frame unless we know it still points to valid memory. */
865
+ _PyInterpreterFrame * frame = (_PyInterpreterFrame * )f -> _f_frame_data ;
866
+
864
867
/* Kill all local variables including specials, if we own them */
865
- if (f -> f_frame -> owner == FRAME_OWNED_BY_FRAME_OBJECT ) {
866
- assert (f -> f_frame == (_PyInterpreterFrame * )f -> _f_frame_data );
867
- _PyInterpreterFrame * frame = (_PyInterpreterFrame * )f -> _f_frame_data ;
868
+ if (f -> f_frame == frame && frame -> owner == FRAME_OWNED_BY_FRAME_OBJECT ) {
868
869
/* Don't clear code object until the end */
869
870
co = frame -> f_code ;
870
871
frame -> f_code = NULL ;
You can’t perform that action at this time.
0 commit comments