Skip to content

Commit 57e50d9

Browse files
kumaraditya303mrahtz
authored andcommitted
pythongh-107803: fix thread safety issue in double linked list implementation (python#121007)
1 parent f988fa2 commit 57e50d9

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

Include/internal/pycore_object.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n)
126126
}
127127
#define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n)
128128

129-
extern void _Py_SetImmortal(PyObject *op);
130-
extern void _Py_SetImmortalUntracked(PyObject *op);
129+
PyAPI_FUNC(void) _Py_SetImmortal(PyObject *op);
130+
PyAPI_FUNC(void) _Py_SetImmortalUntracked(PyObject *op);
131131

132132
// Makes an immortal object mortal again with the specified refcnt. Should only
133133
// be used during runtime finalization.

Modules/_asynciomodule.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "pycore_dict.h" // _PyDict_GetItem_KnownHash()
77
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
88
#include "pycore_moduleobject.h" // _PyModule_GetState()
9+
#include "pycore_object.h" // _Py_SetImmortalUntracked
910
#include "pycore_pyerrors.h" // _PyErr_ClearExcState()
1011
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
1112
#include "pycore_pystate.h" // _PyThreadState_GET()
@@ -3706,6 +3707,7 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
37063707
}
37073708
Py_DECREF(eager_iter);
37083709
TaskObj *head = state->asyncio_tasks.head;
3710+
Py_INCREF(head);
37093711
assert(head != NULL);
37103712
assert(head->prev == NULL);
37113713
TaskObj *tail = &state->asyncio_tasks.tail;
@@ -3714,10 +3716,11 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
37143716
if (add_one_task(state, tasks, (PyObject *)head, loop) < 0) {
37153717
Py_DECREF(tasks);
37163718
Py_DECREF(loop);
3719+
Py_DECREF(head);
37173720
return NULL;
37183721
}
3719-
head = head->next;
3720-
assert(head != NULL);
3722+
Py_INCREF(head->next);
3723+
Py_SETREF(head, head->next);
37213724
}
37223725
PyObject *scheduled_iter = PyObject_GetIter(state->non_asyncio_tasks);
37233726
if (scheduled_iter == NULL) {
@@ -3944,6 +3947,8 @@ static int
39443947
module_exec(PyObject *mod)
39453948
{
39463949
asyncio_state *state = get_asyncio_state(mod);
3950+
Py_SET_TYPE(&state->asyncio_tasks.tail, state->TaskType);
3951+
_Py_SetImmortalUntracked((PyObject *)&state->asyncio_tasks.tail);
39473952
state->asyncio_tasks.head = &state->asyncio_tasks.tail;
39483953

39493954
#define CREATE_TYPE(m, tp, spec, base) \

0 commit comments

Comments
 (0)