From bcb198385dee469d630a184182df9dc1463e2c47 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 8 Jun 2020 02:14:47 +0200 Subject: bpo-40887: Don't use finalized free lists (GH-20700) In debug mode, ensure that free lists are no longer used after being finalized. Set numfree to -1 in finalization functions (eg. _PyList_Fini()), and then check that numfree is not equal to -1 before using a free list (e.g list_dealloc()). --- Objects/frameobject.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Objects/frameobject.c') diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 0fe9f2a666..0dad42ee7b 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -595,6 +595,10 @@ frame_dealloc(PyFrameObject *f) else { PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_frame_state *state = &interp->frame; +#ifdef Py_DEBUG + // frame_dealloc() must not be called after _PyFrame_Fini() + assert(state->numfree != -1); +#endif if (state->numfree < PyFrame_MAXFREELIST) { ++state->numfree; f->f_back = state->free_list; @@ -790,6 +794,10 @@ frame_alloc(PyCodeObject *code) } } else { +#ifdef Py_DEBUG + // frame_alloc() must not be called after _PyFrame_Fini() + assert(state->numfree != -1); +#endif assert(state->numfree > 0); --state->numfree; f = state->free_list; @@ -1188,6 +1196,10 @@ void _PyFrame_Fini(PyThreadState *tstate) { _PyFrame_ClearFreeList(tstate); +#ifdef Py_DEBUG + struct _Py_frame_state *state = &tstate->interp->frame; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ -- cgit v1.2.1