gh-126316: Make grp.getgrall() thread-safe: add a mutex (#127055) · python/cpython@3c2bd66

8 files changed

lines changed

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)

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.

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
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 -