From 63bfa8356090ed01860261b873c516d1d1453bbb Mon Sep 17 00:00:00 2001 From: Alessio Attilio <283363374+inbilico@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:06:14 +0200 Subject: [PATCH] gh-146102: Fix use-after-free and exception leak in crossinterp subsystem --- .../Core_and_Builtins/2026-07-20.gh-issue-146102.1yR78A.rst | 1 + Python/crossinterp.c | 6 +++--- Python/crossinterp_data_lookup.h | 1 + Python/crossinterp_exceptions.h | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-20.gh-issue-146102.1yR78A.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-20.gh-issue-146102.1yR78A.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-20.gh-issue-146102.1yR78A.rst new file mode 100644 index 00000000000000..4a5e3e734d41fa --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-20.gh-issue-146102.1yR78A.rst @@ -0,0 +1 @@ +Fixed a use-after-free in _ensure_notshareableerror and an exception leak in _PyXI_UnwrapNotShareableError and a use-after-free in _get_xidata within the cross-interpreter data subsystem. diff --git a/Python/crossinterp.c b/Python/crossinterp.c index ed77c1be646e27..6541119b36eee8 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -491,24 +491,24 @@ _get_xidata(PyThreadState *tstate, Py_DECREF(obj); return -1; } - // Fall back to obj - Py_DECREF(obj); if (!_PyErr_Occurred(tstate)) { _set_xid_lookup_failure(tstate, obj, NULL, NULL); } + Py_DECREF(obj); return -1; } int res = getdata.basic != NULL ? getdata.basic(tstate, obj, xidata) : getdata.fallback(tstate, obj, fallback, xidata); - Py_DECREF(obj); if (res != 0) { PyObject *cause = _PyErr_GetRaisedException(tstate); assert(cause != NULL); _set_xid_lookup_failure(tstate, obj, NULL, cause); Py_XDECREF(cause); + Py_DECREF(obj); return -1; } + Py_DECREF(obj); // Fill in the blanks and validate the result. _PyXIData_INTERPID(xidata) = PyInterpreterState_GetID(interp); diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h index 54422ad2335cb6..3975d1d6dc2e08 100644 --- a/Python/crossinterp_data_lookup.h +++ b/Python/crossinterp_data_lookup.h @@ -100,6 +100,7 @@ _PyXI_UnwrapNotShareableError(PyThreadState * tstate, _PyXI_failure *failure) if (failure != NULL) { _PyXI_errcode code = _PyXI_ERR_NOT_SHAREABLE; if (_PyXI_InitFailure(failure, code, exc) < 0) { + _PyErr_SetRaisedException(tstate, exc); return -1; } } diff --git a/Python/crossinterp_exceptions.h b/Python/crossinterp_exceptions.h index 98411adc5eb3f6..0d144ffdaf4f5b 100644 --- a/Python/crossinterp_exceptions.h +++ b/Python/crossinterp_exceptions.h @@ -83,6 +83,7 @@ _ensure_notshareableerror(PyThreadState *tstate, // A NotShareableError instance is already set. assert(cause == NULL); _PyErr_SetRaisedException(tstate, ctx); + return; } } else {