diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 29da9936b65504..e71f4ea8cb6b45 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -7,6 +7,8 @@ #include "Python.h" #include "posixmodule.h" +#include "pycore_list.h" // _PyList_AppendTakeRef() +#include "pycore_object.h" // _PyObject_IsUniquelyReferenced() #include // ERANGE #include // getgrgid_r() @@ -290,18 +292,19 @@ grp_getgrall_impl(PyObject *module) setgrent(); struct group *p; + // `d` is a local list; append items without a lock using + // _PyList_AppendTakeRef() within the loop. + assert(_PyObject_IsUniquelyReferenced(d)); while ((p = getgrent()) != NULL) { // gh-126316: Don't release the mutex around mkgrent() since // setgrent()/endgrent() are not reentrant / thread-safe. A deadlock // is unlikely since mkgrent() should not be able to call arbitrary // Python code. PyObject *v = mkgrent(module, p); - if (v == NULL || PyList_Append(d, v) != 0) { - Py_XDECREF(v); + if (v == NULL || _PyList_AppendTakeRef((PyListObject *)d, v) != 0) { Py_CLEAR(d); goto done; } - Py_DECREF(v); } done: