Skip to content

Commit d926271

Browse files
gh-142572: Fix data race when accessing func_code in PyFunctionObject
1 parent 0eaf260 commit d926271

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixing race condition in PyFunctionObject.func_code

Objects/funcobject.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,8 @@ func_get_code(PyObject *self, void *Py_UNUSED(ignored))
631631
return NULL;
632632
}
633633

634-
return Py_NewRef(op->func_code);
634+
PyCodeObject *code = _Py_atomic_load_ptr(&op->func_code);
635+
return Py_NewRef(code);
635636
}
636637

637638
static int
@@ -664,7 +665,7 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
664665
return -1;
665666
}
666667

667-
PyObject *func_code = PyFunction_GET_CODE(op);
668+
PyCodeObject *func_code = _Py_atomic_load_ptr(&op->func_code);
668669
int old_flags = ((PyCodeObject *)func_code)->co_flags;
669670
int new_flags = ((PyCodeObject *)value)->co_flags;
670671
int mask = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR;
@@ -679,7 +680,10 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
679680

680681
handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value);
681682
_PyFunction_ClearVersion(op);
682-
Py_XSETREF(op->func_code, Py_NewRef(value));
683+
PyCodeObject *new = (PyCodeObject *)Py_NewRef(value);
684+
PyCodeObject *old =
685+
(PyCodeObject *)_Py_atomic_exchange_ptr(&op->func_code, new);
686+
Py_XDECREF(old);
683687
return 0;
684688
}
685689

0 commit comments

Comments
 (0)