From: Victor Stinner Date: Tue, 7 Sep 2021 13:42:11 +0000 (+0200) Subject: bpo-44348: BaseException deallocator uses trashcan (GH-28190) X-Git-Tag: v3.11.0a1~237 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fb305092a5d7894b41f122c1a1117b3abf4c567e;p=thirdparty%2FPython%2Fcpython.git bpo-44348: BaseException deallocator uses trashcan (GH-28190) The deallocator function of the BaseException type now uses the trashcan mecanism to prevent stack overflow. For example, when a RecursionError instance is raised, it can be linked to another RecursionError through the __context__ attribute or the __traceback__ attribute, and then a chain of exceptions is created. When the chain is destroyed, nested deallocator function calls can crash with a stack overflow if the chain is too long compared to the available stack memory. --- diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst new file mode 100644 index 000000000000..c222a07725b8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst @@ -0,0 +1,8 @@ +The deallocator function of the :exc:`BaseException` type now uses the +trashcan mecanism to prevent stack overflow. For example, when a +:exc:`RecursionError` instance is raised, it can be linked to another +RecursionError through the ``__context__`` attribute or the +``__traceback__`` attribute, and then a chain of exceptions is created. When +the chain is destroyed, nested deallocator function calls can crash with a +stack overflow if the chain is too long compared to the available stack +memory. Patch by Victor Stinner. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index c6a7aa4aeccf..714039ee1abc 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -89,9 +89,14 @@ BaseException_clear(PyBaseExceptionObject *self) static void BaseException_dealloc(PyBaseExceptionObject *self) { - _PyObject_GC_UNTRACK(self); + PyObject_GC_UnTrack(self); + // bpo-44348: The trashcan mecanism prevents stack overflow when deleting + // long chains of exceptions. For example, exceptions can be chained + // through the __context__ attributes or the __traceback__ attribute. + Py_TRASHCAN_BEGIN(self, BaseException_dealloc) BaseException_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); + Py_TRASHCAN_END } static int