summaryrefslogtreecommitdiffstats
path: root/Objects/classobject.c
diff options
context:
space:
mode:
authorDino Viehland <dinoviehland@meta.com>2024-05-06 17:50:35 (GMT)
committerGitHub <noreply@github.com>2024-05-06 17:50:35 (GMT)
commit5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6 (patch)
treea9b79e4cb8e0a9d1d648e21619382a03363c1f46 /Objects/classobject.c
parente6b213ee3ffb05f067d30cb8bb45681887212444 (diff)
downloadcpython-5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6.zip
cpython-5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6.tar.gz
cpython-5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6.tar.bz2
gh-118362: Fix thread safety around lookups from the type cache in the face of concurrent mutators (#118454)
Add _PyType_LookupRef and use incref before setting attribute on type Makes setting an attribute on a class and signaling type modified atomic Avoid adding re-entrancy exposing the type cache in an inconsistent state by decrefing after type is updated
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r--Objects/classobject.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 9cbb944..69a7d5f 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -188,15 +188,18 @@ method_getattro(PyObject *obj, PyObject *name)
if (PyType_Ready(tp) < 0)
return NULL;
}
- descr = _PyType_Lookup(tp, name);
+ descr = _PyType_LookupRef(tp, name);
}
if (descr != NULL) {
descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
- if (f != NULL)
- return f(descr, obj, (PyObject *)Py_TYPE(obj));
+ if (f != NULL) {
+ PyObject *res = f(descr, obj, (PyObject *)Py_TYPE(obj));
+ Py_DECREF(descr);
+ return res;
+ }
else {
- return Py_NewRef(descr);
+ return descr;
}
}
@@ -410,14 +413,17 @@ instancemethod_getattro(PyObject *self, PyObject *name)
if (PyType_Ready(tp) < 0)
return NULL;
}
- descr = _PyType_Lookup(tp, name);
+ descr = _PyType_LookupRef(tp, name);
if (descr != NULL) {
descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr));
- if (f != NULL)
- return f(descr, self, (PyObject *)Py_TYPE(self));
+ if (f != NULL) {
+ PyObject *res = f(descr, self, (PyObject *)Py_TYPE(self));
+ Py_DECREF(descr);
+ return res;
+ }
else {
- return Py_NewRef(descr);
+ return descr;
}
}