Skip to content

Commit 3c2bd66

Browse files
authored
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.
1 parent 60ec854 commit 3c2bd66

File tree

8 files changed

+107
-22
lines changed

8 files changed

+107
-22
lines changed

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ struct _Py_global_strings {
471471
STRUCT_FOR_ID(hi)
472472
STRUCT_FOR_ID(hook)
473473
STRUCT_FOR_ID(hour)
474+
STRUCT_FOR_ID(id)
474475
STRUCT_FOR_ID(ident)
475476
STRUCT_FOR_ID(identity_hint)
476477
STRUCT_FOR_ID(ignore)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
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: 77 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/grpmodule.c

Lines changed: 20 additions & 11 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"
@@ -281,23 +280,33 @@ static PyObject *
281280
grp_getgrall_impl(PyObject *module)
282281
/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/
283282
{
284-
PyObject *d;
285-
struct group *p;
286-
287-
if ((d = PyList_New(0)) == NULL)
283+
PyObject *d = PyList_New(0);
284+
if (d == NULL) {
288285
return NULL;
286+
}
287+
288+
static PyMutex getgrall_mutex = {0};
289+
PyMutex_Lock(&getgrall_mutex);
289290
setgrent();
291+
292+
struct group *p;
290293
while ((p = getgrent()) != NULL) {
294+
// gh-126316: Don't release the mutex around mkgrent() since
295+
// setgrent()/endgrent() are not reentrant / thread-safe. A deadlock
296+
// is unlikely since mkgrent() should not be able to call arbitrary
297+
// Python code.
291298
PyObject *v = mkgrent(module, p);
292299
if (v == NULL || PyList_Append(d, v) != 0) {
293300
Py_XDECREF(v);
294-
Py_DECREF(d);
295-
endgrent();
296-
return NULL;
301+
Py_CLEAR(d);
302+
goto done;
297303
}
298304
Py_DECREF(v);
299305
}
306+
307+
done:
300308
endgrent();
309+
PyMutex_Unlock(&getgrall_mutex);
301310
return d;
302311
}
303312

Tools/c-analyzer/cpython/ignored.tsv

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

741741
## other
742+
Modules/grpmodule.c grp_getgrall_impl getgrall_mutex -
742743
Modules/_io/_iomodule.c - _PyIO_Module -
743744
Modules/_sqlite/module.c - _sqlite3module -
744745
Modules/clinic/md5module.c.h _md5_md5 _keywords -

0 commit comments

Comments
 (0)