diff --git a/Misc/NEWS.d/next/Library/2024-11-06-12-29-28.gh-issue-126316.X0zQqr.rst b/Misc/NEWS.d/next/Library/2024-11-06-12-29-28.gh-issue-126316.X0zQqr.rst new file mode 100644 index 00000000000000..52a84138b39339 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-06-12-29-28.gh-issue-126316.X0zQqr.rst @@ -0,0 +1,2 @@ +:mod:`grp`: Fix segfault on concurrent calls on Free Threaded build by using +critical sections. Patch by Victor Stinner. diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index cc0ad210f42743..ad809ee81a6e1f 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() + PyDoc_STRVAR(grp_getgrgid__doc__, "getgrgid($module, /, id)\n" "--\n" @@ -26,7 +28,9 @@ grp_getgrgid(PyObject *module, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:getgrgid", _keywords, &id)) goto exit; + Py_BEGIN_CRITICAL_SECTION(module); return_value = grp_getgrgid_impl(module, id); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -56,7 +60,9 @@ grp_getgrnam(PyObject *module, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U:getgrnam", _keywords, &name)) goto exit; + Py_BEGIN_CRITICAL_SECTION(module); return_value = grp_getgrnam_impl(module, name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -80,6 +86,12 @@ grp_getgrall_impl(PyObject *module); static PyObject * grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return grp_getgrall_impl(module); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(module); + return_value = grp_getgrall_impl(module); + Py_END_CRITICAL_SECTION(); + + return return_value; } -/*[clinic end generated code: output=81f180beb67fc585 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dfcdb3a6951a1805 input=a9049054013a1b77]*/ diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index f7d3e12f347ec2..73bee3ebc7f054 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -1,9 +1,17 @@ -/* UNIX group file access module */ +/* UNIX group file access module + * + * Use @critical_section since getgrgid(), getgrnam() and getgrall() are not + * thread safe (gh-126316). + */ // Need limited C API version 3.13 for PyMem_RawRealloc() #include "pyconfig.h" // Py_GIL_DISABLED #ifndef Py_GIL_DISABLED -#define Py_LIMITED_API 0x030d0000 +# define Py_LIMITED_API 0x030d0000 +#else +# ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +# endif #endif #include "Python.h" @@ -111,6 +119,7 @@ mkgrent(PyObject *module, struct group *p) } /*[clinic input] +@critical_section grp.getgrgid id: object @@ -122,7 +131,7 @@ If id is not valid, raise KeyError. static PyObject * grp_getgrgid_impl(PyObject *module, PyObject *id) -/*[clinic end generated code: output=30797c289504a1ba input=15fa0e2ccf5cda25]*/ +/*[clinic end generated code: output=30797c289504a1ba input=f5bf2ce5d1b3d6bc]*/ { PyObject *retval = NULL; int nomem = 0; @@ -191,6 +200,7 @@ grp_getgrgid_impl(PyObject *module, PyObject *id) } /*[clinic input] +@critical_section grp.getgrnam name: unicode @@ -202,7 +212,7 @@ If name is not valid, raise KeyError. static PyObject * grp_getgrnam_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=67905086f403c21c input=08ded29affa3c863]*/ +/*[clinic end generated code: output=67905086f403c21c input=da37ffb830c57159]*/ { char *buf = NULL, *buf2 = NULL, *name_chars; int nomem = 0; @@ -269,6 +279,7 @@ grp_getgrnam_impl(PyObject *module, PyObject *name) } /*[clinic input] +@critical_section grp.getgrall Return a list of all available group entries, in arbitrary order. @@ -279,7 +290,7 @@ to use YP/NIS and may not be accessible via getgrnam or getgrgid. static PyObject * grp_getgrall_impl(PyObject *module) -/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/ +/*[clinic end generated code: output=585dad35e2e763d7 input=b257403558f07a1d]*/ { PyObject *d; struct group *p;