summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2024-11-04 21:59:16 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2024-11-04 21:59:16 +0000
commit440fa9681669edc3ab6d57985886cf874651b334 (patch)
treeac3c3c98c034b667ef754d42a03ad6c3754d5ce3
parentfb9348cbdf5296f2eaba2d14073d6cb6b3cb1e41 (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@
-rw-r--r--lib/libc/gen/initgroups.c11
-rw-r--r--sbin/mountd/mountd.c11
-rw-r--r--usr.bin/id/id.c23
-rw-r--r--usr.bin/ssh/groupaccess.c11
-rw-r--r--usr.sbin/authpf/authpf.c13
5 files changed, 48 insertions, 21 deletions
diff --git a/lib/libc/gen/initgroups.c b/lib/libc/gen/initgroups.c
index 8f60409dcfd..c19e5c8ddd2 100644
--- a/lib/libc/gen/initgroups.c
+++ b/lib/libc/gen/initgroups.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: initgroups.c,v 1.11 2019/06/28 13:32:41 deraadt Exp $ */
+/* $OpenBSD: initgroups.c,v 1.12 2024/11/04 21:59:15 jca Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,10 +37,13 @@ int
initgroups(const char *uname, gid_t agroup)
{
gid_t groups[NGROUPS_MAX];
- int ngroups;
+ int maxgroups, ngroups;
- ngroups = NGROUPS_MAX;
- (void) getgrouplist(uname, agroup, groups, &ngroups);
+ maxgroups = ngroups = NGROUPS_MAX;
+ if (getgrouplist(uname, agroup, groups, &ngroups) == -1) {
+ /* Silently truncate group list */
+ ngroups = maxgroups;
+ }
if (setgroups(ngroups, groups) == -1)
return (-1);
return (0);
diff --git a/sbin/mountd/mountd.c b/sbin/mountd/mountd.c
index 0ca61b39eb4..943b2fe7fad 100644
--- a/sbin/mountd/mountd.c
+++ b/sbin/mountd/mountd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mountd.c,v 1.92 2024/05/21 05:00:47 jsg Exp $ */
+/* $OpenBSD: mountd.c,v 1.93 2024/11/04 21:59:15 jca Exp $ */
/* $NetBSD: mountd.c,v 1.31 1996/02/18 11:57:53 fvdl Exp $ */
/*
@@ -2157,7 +2157,7 @@ parsecred(char *namelist, struct xucred *cr)
char *name, *names;
struct passwd *pw;
struct group *gr;
- int ngroups, cnt;
+ int maxgroups, ngroups, cnt;
/*
* Set up the unprivileged user.
@@ -2182,9 +2182,12 @@ parsecred(char *namelist, struct xucred *cr)
return;
}
cr->cr_uid = pw->pw_uid;
- ngroups = NGROUPS_MAX + 1;
- if (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) {
syslog(LOG_ERR, "Too many groups for %s: %m", pw->pw_name);
+ /* Truncate group list */
+ ngroups = maxgroups;
+ }
/*
* compress out duplicate
*/
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;
diff --git a/usr.bin/ssh/groupaccess.c b/usr.bin/ssh/groupaccess.c
index 69fd007fe15..5303688ba03 100644
--- a/usr.bin/ssh/groupaccess.c
+++ b/usr.bin/ssh/groupaccess.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: groupaccess.c,v 1.17 2019/03/06 22:14:23 dtucker Exp $ */
+/* $OpenBSD: groupaccess.c,v 1.18 2024/11/04 21:59:15 jca Exp $ */
/*
* Copyright (c) 2001 Kevin Steves. All rights reserved.
*
@@ -48,15 +48,18 @@ int
ga_init(const char *user, gid_t base)
{
gid_t groups_bygid[NGROUPS_MAX + 1];
- int i, j;
+ int i, j, maxgroups;
struct group *gr;
if (ngroups > 0)
ga_free();
- ngroups = sizeof(groups_bygid) / sizeof(gid_t);
- if (getgrouplist(user, base, groups_bygid, &ngroups) == -1)
+ maxgroups = ngroups = sizeof(groups_bygid) / sizeof(gid_t);
+ if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) {
logit("getgrouplist: groups list too small");
+ /* Truncate group list */
+ ngroups = maxgroups;
+ }
for (i = 0, j = 0; i < ngroups; i++)
if ((gr = getgrgid(groups_bygid[i])) != NULL)
groups_byname[j++] = xstrdup(gr->gr_name);
diff --git a/usr.sbin/authpf/authpf.c b/usr.sbin/authpf/authpf.c
index 67d2f723705..bc410c0631c 100644
--- a/usr.sbin/authpf/authpf.c
+++ b/usr.sbin/authpf/authpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authpf.c,v 1.129 2022/01/28 06:33:26 guenther Exp $ */
+/* $OpenBSD: authpf.c,v 1.130 2024/11/04 21:59:15 jca Exp $ */
/*
* Copyright (C) 1998 - 2007 Bob Beck (beck@openbsd.org).
@@ -528,8 +528,17 @@ allowed_luser(struct passwd *pw)
}
if (!gl_init) {
- (void) getgrouplist(pw->pw_name,
+ int maxgroups, ret;
+
+ maxgroups = ngroups;
+ ret = getgrouplist(pw->pw_name,
pw->pw_gid, groups, &ngroups);
+ if (ret == -1) {
+ /*
+ * Silently truncate group list
+ */
+ ngroups = maxgroups;
+ }
gl_init++;
}