]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-131401: fix data races in exception handling (#131447)
authorKumar Aditya <kumaraditya@python.org>
Thu, 20 Mar 2025 06:32:05 +0000 (12:02 +0530)
committerGitHub <noreply@github.com>
Thu, 20 Mar 2025 06:32:05 +0000 (12:02 +0530)
Python/ceval.c
Python/errors.c

index 42f5eaddd2e5108f8643f1f7696e9b21a891fad3..0090a2c79ec7ef5b01fb7a288a4d865360d7ebe8 100644 (file)
@@ -3120,7 +3120,7 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg
     }
     else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
         PyObject *exc = _PyErr_GetRaisedException(tstate);
-        PyObject *args = ((PyBaseExceptionObject *)exc)->args;
+        PyObject *args = PyException_GetArgs(exc);
         if (exc && PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1) {
             _PyErr_Clear(tstate);
             PyObject *funcstr = _PyObject_FunctionStr(func);
@@ -3137,6 +3137,7 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg
         else {
             _PyErr_SetRaisedException(tstate, exc);
         }
+        Py_DECREF(args);
     }
 }
 
index 306fb073bc2296d3649d4e5c4810cec2e926199d..14999d6dbaf72ef799250804dd2a9c02fbb3bd33 100644 (file)
@@ -517,7 +517,7 @@ _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
     }
     else {
         *p_type = Py_NewRef(Py_TYPE(exc));
-        *p_traceback = Py_XNewRef(((PyBaseExceptionObject *)exc)->traceback);
+        *p_traceback = PyException_GetTraceback(exc);
     }
 }
 
@@ -545,7 +545,7 @@ PyErr_Clear(void)
 }
 
 static PyObject*
-get_exc_type(PyObject *exc_value)  /* returns a borrowed ref */
+get_exc_type(PyObject *exc_value)  /* returns a strong ref */
 {
     if (exc_value == NULL || exc_value == Py_None) {
         return Py_None;
@@ -554,12 +554,12 @@ get_exc_type(PyObject *exc_value)  /* returns a borrowed ref */
         assert(PyExceptionInstance_Check(exc_value));
         PyObject *type = PyExceptionInstance_Class(exc_value);
         assert(type != NULL);
-        return type;
+        return Py_NewRef(type);
     }
 }
 
 static PyObject*
-get_exc_traceback(PyObject *exc_value)  /* returns a borrowed ref */
+get_exc_traceback(PyObject *exc_value)  /* returns a strong ref */
 {
     if (exc_value == NULL || exc_value == Py_None) {
         return Py_None;
@@ -567,7 +567,6 @@ get_exc_traceback(PyObject *exc_value)  /* returns a borrowed ref */
     else {
         assert(PyExceptionInstance_Check(exc_value));
         PyObject *tb = PyException_GetTraceback(exc_value);
-        Py_XDECREF(tb);
         return tb ? tb : Py_None;
     }
 }
@@ -578,9 +577,9 @@ _PyErr_GetExcInfo(PyThreadState *tstate,
 {
     _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
 
-    *p_type = Py_XNewRef(get_exc_type(exc_info->exc_value));
+    *p_type = get_exc_type(exc_info->exc_value);
     *p_value = Py_XNewRef(exc_info->exc_value);
-    *p_traceback = Py_XNewRef(get_exc_traceback(exc_info->exc_value));
+    *p_traceback = get_exc_traceback(exc_info->exc_value);
 }
 
 PyObject*
@@ -641,14 +640,19 @@ _PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
            exc_value == Py_None ||
            PyExceptionInstance_Check(exc_value));
 
+    PyObject *ret = PyTuple_New(3);
+    if (ret == NULL) {
+        return NULL;
+    }
+
     PyObject *exc_type = get_exc_type(exc_value);
     PyObject *exc_traceback = get_exc_traceback(exc_value);
 
-    return PyTuple_Pack(
-        3,
-        exc_type ? exc_type : Py_None,
-        exc_value ? exc_value : Py_None,
-        exc_traceback ? exc_traceback : Py_None);
+    PyTuple_SET_ITEM(ret, 0, exc_type ? exc_type : Py_None);
+    PyTuple_SET_ITEM(ret, 1, exc_value ? Py_NewRef(exc_value) : Py_None);
+    PyTuple_SET_ITEM(ret, 2, exc_traceback ? exc_traceback : Py_None);
+
+    return ret;
 }