Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit af6fd1f

Browse filesBrowse files
bpo-40014: Fix os.getgrouplist() (GH-19126)
Fix os.getgrouplist(): if getgrouplist() function fails because the group list is too small, retry with a larger group list. On failure, the glibc implementation of getgrouplist() sets ngroups to the total number of groups. For other implementations, double the group list size. (cherry picked from commit f5c7cab) Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 8cd48b6 commit af6fd1f
Copy full SHA for af6fd1f

File tree

2 files changed

+29
-25
lines changed
Filter options

2 files changed

+29
-25
lines changed
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
Fix ``os.getgrouplist()``: on macOS, the ``getgrouplist()`` function returns a
2-
non-zero value without setting ``errno`` if the group list is too small. Double
3-
the list size and call it again in this case.
1+
Fix ``os.getgrouplist()``: if ``getgrouplist()`` function fails because the
2+
group list is too small, retry with a larger group list. On failure, the glibc
3+
implementation of ``getgrouplist()`` sets ``ngroups`` to the total number of
4+
groups. For other implementations, double the group list size.

‎Modules/posixmodule.c

Copy file name to clipboardExpand all lines: Modules/posixmodule.c
+25-22Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6906,37 +6906,40 @@ posix_getgrouplist(PyObject *self, PyObject *args)
69066906
return NULL;
69076907
#endif
69086908

6909+
while (1) {
69096910
#ifdef __APPLE__
6910-
groups = PyMem_New(int, ngroups);
6911+
groups = PyMem_New(int, ngroups);
69116912
#else
6912-
groups = PyMem_New(gid_t, ngroups);
6913+
groups = PyMem_New(gid_t, ngroups);
69136914
#endif
6914-
if (groups == NULL)
6915-
return PyErr_NoMemory();
6915+
if (groups == NULL) {
6916+
return PyErr_NoMemory();
6917+
}
69166918

6917-
#ifdef __APPLE__
6918-
while (getgrouplist(user, basegid, groups, &ngroups)) {
6919-
/* On macOS, getgrouplist() returns a non-zero value without setting
6920-
errno if the group list is too small. Double the list size and call
6921-
it again in this case. */
6919+
int old_ngroups = ngroups;
6920+
if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
6921+
/* Success */
6922+
break;
6923+
}
6924+
6925+
/* getgrouplist() fails if the group list is too small */
69226926
PyMem_Free(groups);
69236927

6924-
if (ngroups > INT_MAX / 2) {
6925-
return PyErr_NoMemory();
6928+
if (ngroups > old_ngroups) {
6929+
/* If the group list is too small, the glibc implementation of
6930+
getgrouplist() sets ngroups to the total number of groups and
6931+
returns -1. */
69266932
}
6927-
ngroups *= 2;
6928-
6929-
groups = PyMem_New(int, ngroups);
6930-
if (groups == NULL) {
6931-
return PyErr_NoMemory();
6933+
else {
6934+
/* Double the group list size */
6935+
if (ngroups > INT_MAX / 2) {
6936+
return PyErr_NoMemory();
6937+
}
6938+
ngroups *= 2;
69326939
}
6940+
6941+
/* Retry getgrouplist() with a larger group list */
69336942
}
6934-
#else
6935-
if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6936-
PyMem_Del(groups);
6937-
return posix_error();
6938-
}
6939-
#endif
69406943

69416944
#ifdef _Py_MEMORY_SANITIZER
69426945
/* Clang memory sanitizer libc intercepts don't know getgrouplist. */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.