https://github.com/python/cpython/commit/70f9b3de36a7aa455f645032d602c5ece3214d45
commit: 70f9b3de36a7aa455f645032d602c5ece3214d45
branch: main
author: Kumar Aditya <kumaradi...@python.org>
committer: kumaraditya303 <kumaradi...@python.org>
date: 2025-05-10T17:38:06Z
summary:

gh-100926: fix thread safety of `ctypes` `__pointer_type__` (#133843)

files:
M Modules/_ctypes/_ctypes.c
M Modules/_ctypes/clinic/_ctypes.c.h

diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 1bb65e0a64920d..a6606381e492e2 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -576,8 +576,16 @@ _ctypes_CType_Type___sizeof___impl(PyObject *self, 
PyTypeObject *cls)
     return PyLong_FromSsize_t(size);
 }
 
+/*[clinic input]
+@getter
+@critical_section
+_ctypes.CType_Type.__pointer_type__
+
+[clinic start generated code]*/
+
 static PyObject *
-ctype_get_pointer_type(PyObject *self, void *Py_UNUSED(ignored))
+_ctypes_CType_Type___pointer_type___get_impl(PyObject *self)
+/*[clinic end generated code: output=718c9ff10b2b0012 input=ff7498aa6edf487c]*/
 {
     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
     StgInfo *info;
@@ -599,8 +607,16 @@ ctype_get_pointer_type(PyObject *self, void 
*Py_UNUSED(ignored))
     return NULL;
 }
 
+/*[clinic input]
+@setter
+@critical_section
+_ctypes.CType_Type.__pointer_type__
+
+[clinic start generated code]*/
+
 static int
-ctype_set_pointer_type(PyObject *self, PyObject *tp, void *Py_UNUSED(ignored))
+_ctypes_CType_Type___pointer_type___set_impl(PyObject *self, PyObject *value)
+/*[clinic end generated code: output=6259be8ea21693fa input=9b2dc2400c388982]*/
 {
     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
     StgInfo *info;
@@ -612,7 +628,7 @@ ctype_set_pointer_type(PyObject *self, PyObject *tp, void 
*Py_UNUSED(ignored))
         return -1;
     }
 
-    Py_XSETREF(info->pointer_type, Py_XNewRef(tp));
+    Py_XSETREF(info->pointer_type, Py_XNewRef(value));
     return 0;
 }
 
@@ -626,8 +642,7 @@ static PyMethodDef ctype_methods[] = {
 };
 
 static PyGetSetDef ctype_getsets[] = {
-    { "__pointer_type__", ctype_get_pointer_type, ctype_set_pointer_type,
-      "pointer type", NULL },
+    _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF
     { NULL, NULL }
 };
 
@@ -1254,9 +1269,11 @@ PyCPointerType_SetProto(ctypes_state *st, PyObject 
*self, StgInfo *stginfo, PyOb
         return -1;
     }
     Py_XSETREF(stginfo->proto, Py_NewRef(proto));
+    STGINFO_LOCK(info);
     if (info->pointer_type == NULL) {
         Py_XSETREF(info->pointer_type, Py_NewRef(self));
     }
+    STGINFO_UNLOCK();
     return 0;
 }
 
diff --git a/Modules/_ctypes/clinic/_ctypes.c.h 
b/Modules/_ctypes/clinic/_ctypes.c.h
index 92dfb8f83b7da6..d9a2ab19661c3b 100644
--- a/Modules/_ctypes/clinic/_ctypes.c.h
+++ b/Modules/_ctypes/clinic/_ctypes.c.h
@@ -31,6 +31,56 @@ _ctypes_CType_Type___sizeof__(PyObject *self, PyTypeObject 
*cls, PyObject *const
     return _ctypes_CType_Type___sizeof___impl(self, cls);
 }
 
+#if !defined(_ctypes_CType_Type___pointer_type___DOCSTR)
+#  define _ctypes_CType_Type___pointer_type___DOCSTR NULL
+#endif
+#if defined(_CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF)
+#  undef _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF
+#  define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", 
(getter)_ctypes_CType_Type___pointer_type___get, 
(setter)_ctypes_CType_Type___pointer_type___set, 
_ctypes_CType_Type___pointer_type___DOCSTR},
+#else
+#  define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", 
(getter)_ctypes_CType_Type___pointer_type___get, NULL, 
_ctypes_CType_Type___pointer_type___DOCSTR},
+#endif
+
+static PyObject *
+_ctypes_CType_Type___pointer_type___get_impl(PyObject *self);
+
+static PyObject *
+_ctypes_CType_Type___pointer_type___get(PyObject *self, void 
*Py_UNUSED(context))
+{
+    PyObject *return_value = NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    return_value = _ctypes_CType_Type___pointer_type___get_impl(self);
+    Py_END_CRITICAL_SECTION();
+
+    return return_value;
+}
+
+#if !defined(_ctypes_CType_Type___pointer_type___DOCSTR)
+#  define _ctypes_CType_Type___pointer_type___DOCSTR NULL
+#endif
+#if defined(_CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF)
+#  undef _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF
+#  define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", 
(getter)_ctypes_CType_Type___pointer_type___get, 
(setter)_ctypes_CType_Type___pointer_type___set, 
_ctypes_CType_Type___pointer_type___DOCSTR},
+#else
+#  define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", 
NULL, (setter)_ctypes_CType_Type___pointer_type___set, NULL},
+#endif
+
+static int
+_ctypes_CType_Type___pointer_type___set_impl(PyObject *self, PyObject *value);
+
+static int
+_ctypes_CType_Type___pointer_type___set(PyObject *self, PyObject *value, void 
*Py_UNUSED(context))
+{
+    int return_value;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    return_value = _ctypes_CType_Type___pointer_type___set_impl(self, value);
+    Py_END_CRITICAL_SECTION();
+
+    return return_value;
+}
+
 PyDoc_STRVAR(CDataType_from_address__doc__,
 "from_address($self, value, /)\n"
 "--\n"
@@ -1000,4 +1050,4 @@ Simple_from_outparm(PyObject *self, PyTypeObject *cls, 
PyObject *const *args, Py
     }
     return Simple_from_outparm_impl(self, cls);
 }
-/*[clinic end generated code: output=9fb75bf7e9a17df2 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f4bc2a77ec073b8a input=a9049054013a1b77]*/

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to