Skip to content

Commit 9187ac3

Browse files
authored
[3.13] gh-126316: Make grp.getgrall() thread-safe: add a mutex (#127055) (#127104)
* gh-126316: Make grp.getgrall() thread-safe: add a mutex (#127055) grpmodule.c is no longer built with the limited C API, since PyMutex is excluded from the limited C API. (cherry picked from commit 3c2bd66) * Revert ABI changes Don't use Argument Clinic for grp.getgrgid() to avoid changing the ABI (change PyInterpreterState structure by adding an "id" identifier).
1 parent 0f77357 commit 9187ac3

File tree

4 files changed

+82
-59
lines changed

4 files changed

+82
-59
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`grp`: Make :func:`grp.getgrall` thread-safe by adding a mutex. Patch
2+
by Victor Stinner.

Modules/clinic/grpmodule.c.h

Lines changed: 42 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/grpmodule.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
/* UNIX group file access module */
22

3-
// Need limited C API version 3.13 for PyMem_RawRealloc()
4-
#include "pyconfig.h" // Py_GIL_DISABLED
5-
#ifndef Py_GIL_DISABLED
6-
#define Py_LIMITED_API 0x030d0000
3+
// Argument Clinic uses the internal C API
4+
#ifndef Py_BUILD_CORE_BUILTIN
5+
# define Py_BUILD_CORE_MODULE 1
76
#endif
87

98
#include "Python.h"
@@ -110,20 +109,15 @@ mkgrent(PyObject *module, struct group *p)
110109
return v;
111110
}
112111

113-
/*[clinic input]
114-
grp.getgrgid
115-
116-
id: object
117-
118-
Return the group database entry for the given numeric group ID.
119-
120-
If id is not valid, raise KeyError.
121-
[clinic start generated code]*/
122-
123112
static PyObject *
124-
grp_getgrgid_impl(PyObject *module, PyObject *id)
125-
/*[clinic end generated code: output=30797c289504a1ba input=15fa0e2ccf5cda25]*/
113+
grp_getgrgid(PyObject *module, PyObject *args, PyObject *kwargs)
126114
{
115+
static char *kwlist[] = {"id", NULL};
116+
PyObject *id;
117+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &id)) {
118+
return NULL;
119+
}
120+
127121
PyObject *retval = NULL;
128122
int nomem = 0;
129123
char *buf = NULL, *buf2 = NULL;
@@ -190,6 +184,15 @@ grp_getgrgid_impl(PyObject *module, PyObject *id)
190184
return retval;
191185
}
192186

187+
PyDoc_STRVAR(grp_getgrgid__doc__,
188+
"getgrgid($module, /, id)\n"
189+
"--\n"
190+
"\n"
191+
"Return the group database entry for the given numeric group ID.\n"
192+
"\n"
193+
"If id is not valid, raise KeyError.");
194+
195+
193196
/*[clinic input]
194197
grp.getgrnam
195198
@@ -281,28 +284,38 @@ static PyObject *
281284
grp_getgrall_impl(PyObject *module)
282285
/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/
283286
{
284-
PyObject *d;
285-
struct group *p;
286-
287-
if ((d = PyList_New(0)) == NULL)
287+
PyObject *d = PyList_New(0);
288+
if (d == NULL) {
288289
return NULL;
290+
}
291+
292+
static PyMutex getgrall_mutex = {0};
293+
PyMutex_Lock(&getgrall_mutex);
289294
setgrent();
295+
296+
struct group *p;
290297
while ((p = getgrent()) != NULL) {
298+
// gh-126316: Don't release the mutex around mkgrent() since
299+
// setgrent()/endgrent() are not reentrant / thread-safe. A deadlock
300+
// is unlikely since mkgrent() should not be able to call arbitrary
301+
// Python code.
291302
PyObject *v = mkgrent(module, p);
292303
if (v == NULL || PyList_Append(d, v) != 0) {
293304
Py_XDECREF(v);
294-
Py_DECREF(d);
295-
endgrent();
296-
return NULL;
305+
Py_CLEAR(d);
306+
goto done;
297307
}
298308
Py_DECREF(v);
299309
}
310+
311+
done:
300312
endgrent();
313+
PyMutex_Unlock(&getgrall_mutex);
301314
return d;
302315
}
303316

304317
static PyMethodDef grp_methods[] = {
305-
GRP_GETGRGID_METHODDEF
318+
{"getgrgid", _PyCFunction_CAST(grp_getgrgid), METH_VARARGS|METH_KEYWORDS, grp_getgrgid__doc__},
306319
GRP_GETGRNAM_METHODDEF
307320
GRP_GETGRALL_METHODDEF
308321
{NULL, NULL}

Tools/c-analyzer/cpython/ignored.tsv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ Modules/expat/xmlrole.c - declClose -
742742
Modules/expat/xmlrole.c - error -
743743

744744
## other
745+
Modules/grpmodule.c grp_getgrall_impl getgrall_mutex -
745746
Modules/_io/_iomodule.c - _PyIO_Module -
746747
Modules/_sqlite/module.c - _sqlite3module -
747748
Modules/clinic/md5module.c.h _md5_md5 _keywords -

0 commit comments

Comments
 (0)