diff options
| author | Victor Stinner <vstinner@python.org> | 2020-06-08 02:14:47 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-08 02:14:47 +0200 |
| commit | bcb198385dee469d630a184182df9dc1463e2c47 (patch) | |
| tree | 193bc5c3584732b506223a34f3215a03fd1be408 /Objects/tupleobject.c | |
| parent | c96a61e8163c2d25ed4ac77cf96201fd0bdb945c (diff) | |
| download | cpython-git-bcb198385dee469d630a184182df9dc1463e2c47.tar.gz | |
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/tupleobject.c')
| -rw-r--r-- | Objects/tupleobject.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 951cd1faf7..8bfa0894a7 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -54,6 +54,10 @@ tuple_alloc(struct _Py_tuple_state *state, Py_ssize_t size) return NULL; } #if PyTuple_MAXSAVESIZE > 0 +#ifdef Py_DEBUG + // tuple_alloc() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif if (size < PyTuple_MAXSAVESIZE && (op = state->free_list[size]) != NULL) { assert(size != 0); state->free_list[size] = (PyTupleObject *) op->ob_item[0]; @@ -102,6 +106,10 @@ PyTuple_New(Py_ssize_t size) } #if PyTuple_MAXSAVESIZE > 0 if (size == 0) { +#ifdef Py_DEBUG + // PyTuple_New() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif state->free_list[0] = op; ++state->numfree[0]; Py_INCREF(op); /* extra INCREF so that this is never freed */ @@ -227,6 +235,10 @@ tupledealloc(PyTupleObject *op) #if PyTuple_MAXSAVESIZE > 0 PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_tuple_state *state = &interp->tuple; +#ifdef Py_DEBUG + // tupledealloc() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif if (len < PyTuple_MAXSAVESIZE && state->numfree[len] < PyTuple_MAXFREELIST && Py_IS_TYPE(op, &PyTuple_Type)) @@ -984,6 +996,9 @@ _PyTuple_Fini(PyThreadState *tstate) Py_CLEAR(state->free_list[0]); _PyTuple_ClearFreeList(tstate); +#ifdef Py_DEBUG + state->numfree[0] = -1; +#endif #endif } |
