diff options
author | Victor Stinner <vstinner@python.org> | 2020-06-08 00:14:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-08 00:14:47 (GMT) |
commit | bcb198385dee469d630a184182df9dc1463e2c47 (patch) | |
tree | 193bc5c3584732b506223a34f3215a03fd1be408 /Objects/floatobject.c | |
parent | c96a61e8163c2d25ed4ac77cf96201fd0bdb945c (diff) | |
download | cpython-bcb198385dee469d630a184182df9dc1463e2c47.zip cpython-bcb198385dee469d630a184182df9dc1463e2c47.tar.gz cpython-bcb198385dee469d630a184182df9dc1463e2c47.tar.bz2 |
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()).
Diffstat (limited to 'Objects/floatobject.c')
-rw-r--r-- | Objects/floatobject.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d72fd21..65625fe 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -116,6 +116,10 @@ PyFloat_FromDouble(double fval) struct _Py_float_state *state = &interp->float_state; PyFloatObject *op = state->free_list; if (op != NULL) { +#ifdef Py_DEBUG + // PyFloat_FromDouble() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif state->free_list = (PyFloatObject *) Py_TYPE(op); state->numfree--; } @@ -219,6 +223,10 @@ float_dealloc(PyFloatObject *op) if (PyFloat_CheckExact(op)) { PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_float_state *state = &interp->float_state; +#ifdef Py_DEBUG + // float_dealloc() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif if (state->numfree >= PyFloat_MAXFREELIST) { PyObject_FREE(op); return; @@ -1984,10 +1992,11 @@ void _PyFloat_ClearFreeList(PyThreadState *tstate) { struct _Py_float_state *state = &tstate->interp->float_state; - PyFloatObject *f = state->free_list, *next; - for (; f; f = next) { - next = (PyFloatObject*) Py_TYPE(f); + PyFloatObject *f = state->free_list; + while (f != NULL) { + PyFloatObject *next = (PyFloatObject*) Py_TYPE(f); PyObject_FREE(f); + f = next; } state->free_list = NULL; state->numfree = 0; @@ -1997,6 +2006,10 @@ void _PyFloat_Fini(PyThreadState *tstate) { _PyFloat_ClearFreeList(tstate); +#ifdef Py_DEBUG + struct _Py_float_state *state = &tstate->interp->float_state; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ |