]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40014: Fix os.getgrouplist() on macOS (GH-19118)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 23 Mar 2020 19:18:41 +0000 (12:18 -0700)
committerGitHub <noreply@github.com>
Mon, 23 Mar 2020 19:18:41 +0000 (12:18 -0700)
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 <vstinner@python.org>
Misc/NEWS.d/next/Library/2020-03-23-17-52-00.bpo-40014.Ya70VG.rst [new file with mode: 0644]
Modules/posixmodule.c

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 (file)
index 0000000..58f14fa
--- /dev/null
@@ -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.
index 2f791d1df953a06f95ea868c8809c43b63d4781d..be7ebb67d21eef5ac754627b5e5d10dae839b489 100644 (file)
@@ -6914,10 +6914,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. */