diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2024-11-04 21:59:16 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2024-11-04 21:59:16 +0000 |
commit | 440fa9681669edc3ab6d57985886cf874651b334 (patch) | |
tree | ac3c3c98c034b667ef754d42a03ad6c3754d5ce3 /usr.bin/id | |
parent | fb9348cbdf5296f2eaba2d14073d6cb6b3cb1e41 (diff) |
Ignore extra groups that don't fit in the buffer passed to getgrouplist(3)
Our kernel supports 16 groups (NGROUPS_MAX), but nothing prevents
an admin from adding a user to more groups. With that tweak we'll keep
on ignoring them instead of potentially reading past the buffer passed to
getgrouplist(3). That behavior is explicitely described in initgroups(3).
ok millert@ gilles@
Diffstat (limited to 'usr.bin/id')
-rw-r--r-- | usr.bin/id/id.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/usr.bin/id/id.c b/usr.bin/id/id.c index bb1ebc0e3fd..02c3d2a1e98 100644 --- a/usr.bin/id/id.c +++ b/usr.bin/id/id.c @@ -1,4 +1,4 @@ -/* $OpenBSD: id.c,v 1.30 2023/05/30 16:44:16 op Exp $ */ +/* $OpenBSD: id.c,v 1.31 2024/11/04 21:59:15 jca Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -269,7 +269,7 @@ void user(struct passwd *pw) { gid_t gid, groups[NGROUPS_MAX + 1]; - int cnt, ngroups; + int cnt, maxgroups, ngroups; uid_t uid; struct group *gr; char *prefix; @@ -279,8 +279,11 @@ user(struct passwd *pw) (void)printf(" gid=%u", pw->pw_gid); if ((gr = getgrgid(pw->pw_gid))) (void)printf("(%s)", gr->gr_name); - ngroups = NGROUPS_MAX + 1; - (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); + maxgroups = ngroups = NGROUPS_MAX + 1; + if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) { + /* Silently truncate group list */ + ngroups = maxgroups; + } prefix = " groups="; for (cnt = 0; cnt < ngroups;) { gid = groups[cnt]; @@ -298,14 +301,20 @@ user(struct passwd *pw) void group(struct passwd *pw, int nflag) { - int cnt, ngroups; + int cnt, maxgroups, ngroups; gid_t gid, groups[NGROUPS_MAX + 1]; struct group *gr; char *prefix; if (pw) { - ngroups = NGROUPS_MAX + 1; - (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); + int ret; + + maxgroups = ngroups = NGROUPS_MAX + 1; + ret = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); + if (ret == -1) { + /* Silently truncate group list */ + ngroups = maxgroups; + } } else { groups[0] = getgid(); ngroups = getgroups(NGROUPS_MAX, groups + 1) + 1; |