Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

gh-127945: fix thread safety of creating instances of ctypes structures #131716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 30, 2025
Prev Previous commit
Next Next commit
improve comments
  • Loading branch information
kumaraditya303 committed Mar 25, 2025
commit b0e06a083539a280b9c20c61e445727fa6413a4f
10 changes: 6 additions & 4 deletions 10 Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,14 +712,16 @@ StructUnionType_init(PyObject *self, PyObject *args, PyObject *kwds, int isStruc
return 0;
}
int ret = 0;
STGINFO_LOCK2(info, baseinfo);
STGINFO_LOCK(baseinfo);
/* copy base info */
ret = PyCStgInfo_clone(info, baseinfo);
if (ret >= 0) {
stginfo_clear_dict_final_lock_held(info);
stginfo_set_dict_final_lock_held(baseinfo);
// clear the 'final' bit in the subclass info
// safe to modify without atomics as it is not exposed to other threads
info->dict_final = 0;
kumaraditya303 marked this conversation as resolved.
Show resolved Hide resolved
stginfo_set_dict_final_lock_held(baseinfo); /* set the 'final' flag in the baseclass info */
}
STGINFO_UNLOCK2();
STGINFO_UNLOCK();
return ret;
}
return 0;
Expand Down
9 changes: 0 additions & 9 deletions 9 Modules/_ctypes/ctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,7 @@ typedef struct {
*/

#define STGINFO_LOCK(stginfo) Py_BEGIN_CRITICAL_SECTION_MUT(&(stginfo)->mutex)
#define STGINFO_LOCK2(stginfo1, stginfo2) Py_BEGIN_CRITICAL_SECTION2_MUT(&(stginfo1)->mutex, &(stginfo2)->mutex)
#define STGINFO_UNLOCK() Py_END_CRITICAL_SECTION()
#define STGINFO_UNLOCK2() Py_END_CRITICAL_SECTION2()

static inline int
stginfo_get_dict_final(StgInfo *info)
Expand Down Expand Up @@ -455,13 +453,6 @@ stginfo_set_dict_final(StgInfo *info)
STGINFO_UNLOCK();
}

static inline void
stginfo_clear_dict_final_lock_held(StgInfo *info)
{
_Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&info->mutex);
FT_ATOMIC_STORE_INT(info->dict_final, 0);
}

extern int PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info);
extern void ctype_clear_stginfo(StgInfo *info);

Expand Down
5 changes: 3 additions & 2 deletions 5 Modules/_ctypes/stgdict.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
int
PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
{
_Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&src_info->mutex);
_Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&dst_info->mutex);
Py_ssize_t size;

ctype_clear_stginfo(dst_info);
Expand All @@ -36,6 +34,9 @@ PyCStgInfo_clone(StgInfo *dst_info, StgInfo *src_info)
dst_info->ffi_type_pointer.elements = NULL;

memcpy(dst_info, src_info, sizeof(StgInfo));
#ifdef Py_GIL_DISABLED
dst_info->mutex = (PyMutex){0};
#endif

Py_XINCREF(dst_info->proto);
Py_XINCREF(dst_info->argtypes);
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.