From: Mark Shannon Date: Tue, 13 Sep 2022 08:25:16 +0000 (+0100) Subject: GH-96754: Check whether the interpreter frame is complete before creating frame objec... X-Git-Tag: v3.12.0a1~426 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=12c5f328d2479ac3432df5e266adc4e59adeabfe;p=thirdparty%2FPython%2Fcpython.git GH-96754: Check whether the interpreter frame is complete before creating frame object. (GH-96776) --- diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-09-12-16-58-22.gh-issue-96754.0GRme5.rst b/Misc/NEWS.d/next/Core and Builtins/2022-09-12-16-58-22.gh-issue-96754.0GRme5.rst new file mode 100644 index 000000000000..beac84ee822a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-09-12-16-58-22.gh-issue-96754.0GRme5.rst @@ -0,0 +1,3 @@ +Make sure that all frame objects created are created from valid interpreter +frames. Prevents the possibility of invalid frames in backtraces and signal +handlers. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index e3b37f179312..0f30b4da0363 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1832,6 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) _Py_atomic_store(&is_tripped, 0); _PyInterpreterFrame *frame = tstate->cframe->current_frame; + while (frame && _PyFrame_IsIncomplete(frame)) { + frame = frame->previous; + } signal_state_t *state = &signal_global_state; for (int i = 1; i < Py_NSIG; i++) { if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { diff --git a/Python/ceval.c b/Python/ceval.c index 20d0e1c50a5f..091b0eb76407 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5113,9 +5113,11 @@ error: #endif /* Log traceback info. */ - PyFrameObject *f = _PyFrame_GetFrameObject(frame); - if (f != NULL) { - PyTraceBack_Here(f); + if (!_PyFrame_IsIncomplete(frame)) { + PyFrameObject *f = _PyFrame_GetFrameObject(frame); + if (f != NULL) { + PyTraceBack_Here(f); + } } if (tstate->c_tracefunc != NULL) { diff --git a/Python/pystate.c b/Python/pystate.c index a0d61d7ebb3b..23e9d24c591b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1406,6 +1406,9 @@ _PyThread_CurrentFrames(void) PyThreadState *t; for (t = i->threads.head; t != NULL; t = t->next) { _PyInterpreterFrame *frame = t->cframe->current_frame; + while (frame && _PyFrame_IsIncomplete(frame)) { + frame = frame->previous; + } if (frame == NULL) { continue; }