From 8eed594628d150ea13687984b66f7b4ed9c06110 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 24 Jun 2026 14:46:39 +0300 Subject: [PATCH] gh-151763: Fix possible crash on `CodeType` deallocation (GH-152034) (cherry picked from commit 22dd5b5b374c8eb4def7d55bb8de5928e345c73a) Co-authored-by: sobolevn --- ...-06-23-23-48-54.gh-issue-151763.Eu8pYQ.rst | 1 + Objects/codeobject.c | 20 ++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-23-48-54.gh-issue-151763.Eu8pYQ.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-23-48-54.gh-issue-151763.Eu8pYQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-23-48-54.gh-issue-151763.Eu8pYQ.rst new file mode 100644 index 000000000000000..d4746e992f8779d --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-23-48-54.gh-issue-151763.Eu8pYQ.rst @@ -0,0 +1 @@ +Fixes possible crash on :class:`types.CodeType` deallocation. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 4ede8de6e8adc5f..03036020b1cb1ae 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -743,6 +743,10 @@ _PyCode_New(struct _PyCodeConstructor *con) return NULL; } +#ifdef Py_GIL_DISABLED + co->_co_unique_id = _Py_INVALID_UNIQUE_ID; +#endif + if (init_code(co, con) < 0) { Py_DECREF(co); return NULL; @@ -2449,15 +2453,17 @@ code_dealloc(PyObject *self) FT_CLEAR_WEAKREFS(self, co->co_weakreflist); free_monitoring_data(co->_co_monitoring); #ifdef Py_GIL_DISABLED - // The first element always points to the mutable bytecode at the end of - // the code object, which will be freed when the code object is freed. - for (Py_ssize_t i = 1; i < co->co_tlbc->size; i++) { - char *entry = co->co_tlbc->entries[i]; - if (entry != NULL) { - PyMem_Free(entry); + if (co->co_tlbc != NULL) { + // The first element always points to the mutable bytecode at the end of + // the code object, which will be freed when the code object is freed. + for (Py_ssize_t i = 1; i < co->co_tlbc->size; i++) { + char *entry = co->co_tlbc->entries[i]; + if (entry != NULL) { + PyMem_Free(entry); + } } + PyMem_Free(co->co_tlbc); } - PyMem_Free(co->co_tlbc); #endif PyObject_Free(co); }