From 1cdc61c7673f71f2cef57715e482c84efda6d9e0 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 23 Mar 2020 12:21:07 -0700 Subject: [PATCH] bpo-40014: Fix os.getgrouplist() on macOS (GH-19118) On macOS, getgrouplist() returns a non-zero value without setting errno if the group list is too small. Double the list size and call it again in this case. (cherry picked from commit 8ec7370c89aa522602eb9604086ce9f09770953d) Co-authored-by: Victor Stinner --- .../2020-03-23-17-52-00.bpo-40014.Ya70VG.rst | 3 +++ Modules/posixmodule.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-03-23-17-52-00.bpo-40014.Ya70VG.rst diff --git a/Misc/NEWS.d/next/Library/2020-03-23-17-52-00.bpo-40014.Ya70VG.rst b/Misc/NEWS.d/next/Library/2020-03-23-17-52-00.bpo-40014.Ya70VG.rst new file mode 100644 index 00000000000000..58f14fa9a72d07 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-23-17-52-00.bpo-40014.Ya70VG.rst @@ -0,0 +1,3 @@ +Fix ``os.getgrouplist()``: on macOS, the ``getgrouplist()`` function returns a +non-zero value without setting ``errno`` if the group list is too small. Double +the list size and call it again in this case. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 58cb9b0d468d2f..8d456730a38272 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6178,10 +6178,29 @@ posix_getgrouplist(PyObject *self, PyObject *args) if (groups == NULL) return PyErr_NoMemory(); +#ifdef __APPLE__ + while (getgrouplist(user, basegid, groups, &ngroups)) { + /* On macOS, getgrouplist() returns a non-zero value without setting + errno if the group list is too small. Double the list size and call + it again in this case. */ + PyMem_Free(groups); + + if (ngroups > INT_MAX / 2) { + return PyErr_NoMemory(); + } + ngroups *= 2; + + groups = PyMem_New(int, ngroups); + if (groups == NULL) { + return PyErr_NoMemory(); + } + } +#else if (getgrouplist(user, basegid, groups, &ngroups) == -1) { PyMem_Del(groups); return posix_error(); } +#endif #ifdef _Py_MEMORY_SANITIZER /* Clang memory sanitizer libc intercepts don't know getgrouplist. */