Handle GIDs > 2^31 in getgrouplist.

When compiled in 32bit mode, the getgrouplist implementation may fail
for GIDs greater than LONG_MAX.  Analysis and change from ralf.winkel
at tui.com.
This commit is contained in:
Darren Tucker 2021-06-17 21:03:19 +10:00
parent 31fac20c94
commit acb2887a76

View File

@ -445,7 +445,7 @@ getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt)
char *cp, *grplist, *grp; char *cp, *grplist, *grp;
gid_t gid; gid_t gid;
int ret = 0, ngroups = 0, maxgroups; int ret = 0, ngroups = 0, maxgroups;
long l; long long ll;
maxgroups = *grpcnt; maxgroups = *grpcnt;
@ -463,12 +463,12 @@ getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt)
/* copy each entry from getgrset into group list */ /* copy each entry from getgrset into group list */
while ((grp = strsep(&grplist, ",")) != NULL) { while ((grp = strsep(&grplist, ",")) != NULL) {
l = strtol(grp, NULL, 10); ll = strtoll(grp, NULL, 10);
if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) { if (ngroups >= maxgroups || ll < 0 || ll > UID_MAX) {
ret = -1; ret = -1;
goto out; goto out;
} }
gid = (gid_t)l; gid = (gid_t)ll;
if (gid == pgid) if (gid == pgid)
continue; /* we have already added primary gid */ continue; /* we have already added primary gid */
groups[ngroups++] = gid; groups[ngroups++] = gid;