Date: Wed, 17 Jun 2009 19:05:31 -0500 From: Brooks Davis <brooks@freebsd.org> To: freebsd-hackers@freebsd.org, freebsd-current@freebsd.org Subject: Re: CFT: final patches for NGROUPS>>16 Message-ID: <20090618000531.GA46033@lor.one-eyed-alien.net> In-Reply-To: <20090618000407.GA43514@lor.one-eyed-alien.net> References: <20090618000407.GA43514@lor.one-eyed-alien.net>
next in thread | previous in thread | raw e-mail | index | archive | help
--O5XBE6gyVG5Rl6Rj
Content-Type: multipart/mixed; boundary="YZ5djTAD1cGYuMQK"
Content-Disposition: inline
--YZ5djTAD1cGYuMQK
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
As usual, I forgot the attachments. Here they are.
-- Brooks
On Wed, Jun 17, 2009 at 07:04:07PM -0500, Brooks Davis wrote:
> Please find attached three patches which result in raising NGROUPS to
> 1024, making programs in the base system immune to changing values of
> NGROUPS, and pave the way for NGROUPS to be boot time configurable.
>=20
> The first two patches (ngroups-catman.diff and ngroups-posix.diff)
> are userland cleanups. The third (ngroups-main.diff) is the core of
> the change and primairly in the kernel. It is strongly based on work
> contributed by Isilon Systems. The proposed commit messages appear to
> the bottom of this message.
>=20
> I've been running the basic code on my FreeBSD laptop for a while and
> I've tested basic NFS mounts, but more areas need testing before this
> hits a release. Key things to hit include:
> - NFS mount and export
> - IPFW uid, gid, and jail rules
> - portalfs (ideally portalfs should be extended to not truncate groups)
>=20
> In practice, expect appliations to not care about this change unless
> they are run with more than 16 groups. If that happens, calls to
> getgroups() will fail if they use statically sized buffers recompilation
> should fix them.
>=20
> Please test, review, etc. I'd like to get this in before code freeze if
> at all possible.
>=20
> -- Brooks
>=20
> ngroups-catman.diff:
>=20
> When checking if we can write to a file, use access() instead of a
> manual permission check based on stat output. Also, get rid of the
> executability check since it is not used.
>=20
> MFC after: 2 weeks
>=20
> ngroups-posix.diff
>=20
> In preparation for raising NGROUPS and NGROUPS_MAX, change base
> system callers of getgroups(), getgrouplist(), and setgroups() to
> allocate buffers dynamically. Specifically, allocate a buffer of size
> sysconf(_SC_NGROUPS_MAX)+1 (+2 in a few cases to allow for overflow).
>=20
> This (or similar gymnastics) is required for the code to actually follow
> the POSIX.1-2008 specification where {NGROUPS_MAX} may differ at runtime
> and where getgroups may return {NGROUPS_MAX}+1 results on systems like
> FreeBSD which include the primary group.
>=20
> In id(1), don't pointlessly add the primary group to the list of all
> groups, it is always the first result from getgroups(). In principle
> the old code was more portable, but this was only done in one of the two
> places where getgroups() was called to the overall effect was pointless.
>=20
> Document the actual POSIX requirements in the getgroups(2) and
> setgroups(2) manpages. We do not yet support a dynamic NGROUPS, but we
> may in the future.
>=20
> MFC after: 2 weeks
>=20
> ngroups-main.diff:
>=20
> Rework the credential code to support larger values of NGROUPS and
> NGROUPS_MAX, eliminate ABI dependencies on them, and raise the to 1024
> and 1023 respectively. (Previously they were equal, but under a close
> reading of POSIX, NGROUPS_MAX was defined to be too large by 1 since it
> is the number of supplemental groups, not total number of groups.)
>=20
> The bulk of the change consists of converting the struct ucred member
> cr_groups from a static array to a pointer. Do the equivalent in
> kinfo_proc.
>=20
> Introduce new interfaces crcopysafe() and crsetgroups() for duplicating
> a process credential before modifying it and for setting group lists
> respectively. Both interfaces take care for the details of allocating
> groups array. crsetgroups() takes care of truncating the group list
> to the current maximum (NGROUPS) if necessary. In the future,
> crsetgroups() may be responsible for insuring invariants such as sorting
> the supplemental groups to allow groupmember() to be implemented as a
> binary search.
>=20
> Because we can not change struct xucred without breaking application
> ABIs, we leave it alone and introduce a new XU_NGROUPS value which is
> always 16 and is to be used or NGRPS as appropriate for things such as
> NFS which need to use no more than 16 groups. When feasible, truncate
> the group list rather than generating an error.
>=20
> Minor changes:
> - Reduce the number of hand rolled versions of groupmember().
> - Do not assign to both cr_gid and cr_groups[0].
> - Modify ipfw to cache ucreds instead of part of their contents since
> they are immutable once referenced by more than one entity.
>=20
> Submitted by: Isilon Systems
> X-MFC after: never
--YZ5djTAD1cGYuMQK
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="ngroups-catman.diff"
Content-Transfer-Encoding: quoted-printable
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.bin/catman/catman.c ./usr.bin/c=
atman/catman.c
--- /usr/fsvn/head/usr.bin/catman/catman.c 2009-01-22 10:04:12.000000000 -0=
600
+++ ./usr.bin/catman/catman.c 2009-05-08 15:47:47.000000000 -0500
@@ -57,7 +57,6 @@
#define TEST_FILE 0x04
#define TEST_READABLE 0x08
#define TEST_WRITABLE 0x10
-#define TEST_EXECUTABLE 0x20
=20
static int verbose; /* -v flag: be verbose with warnings */
static int pretend; /* -n, -p flags: print out what would be done
@@ -92,9 +91,6 @@
#define GZCAT_CMD "z"
enum Ziptype {NONE, BZIP, GZIP};
=20
-static uid_t uid;
-static gid_t gids[NGROUPS_MAX];
-static int ngids;
static int starting_dir;
static char tmp_file[MAXPATHLEN];
struct stat test_st;
@@ -320,23 +316,10 @@
result |=3D TEST_DIR;
else if (S_ISREG(test_st.st_mode))
result |=3D TEST_FILE;
- if (test_st.st_uid =3D=3D uid) {
- test_st.st_mode >>=3D 6;
- } else {
- int i;
- for (i =3D 0; i < ngids; i++) {
- if (test_st.st_gid =3D=3D gids[i]) {
- test_st.st_mode >>=3D 3;
- break;
- }
- }
- }
- if (test_st.st_mode & S_IROTH)
+ if (access(name, R_OK))
result |=3D TEST_READABLE;
- if (test_st.st_mode & S_IWOTH)
+ if (access(name, W_OK))
result |=3D TEST_WRITABLE;
- if (test_st.st_mode & S_IXOTH)
- result |=3D TEST_EXECUTABLE;
return result;
}
=20
@@ -759,14 +742,6 @@
{
int opt;
=20
- if ((uid =3D getuid()) =3D=3D 0) {
- fprintf(stderr, "don't run %s as root, use:\n echo", argv[0]);
- for (optind =3D 0; optind < argc; optind++) {
- fprintf(stderr, " %s", argv[optind]);
- }
- fprintf(stderr, " | nice -5 su -m man\n");
- exit(1);
- }
while ((opt =3D getopt(argc, argv, "vnfLrh")) !=3D -1) {
switch (opt) {
case 'f':
@@ -789,7 +764,6 @@
/* NOTREACHED */
}
}
- ngids =3D getgroups(NGROUPS_MAX, gids);
if ((starting_dir =3D open(".", 0)) < 0) {
err(1, ".");
}
--YZ5djTAD1cGYuMQK
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="ngroups-posix.diff"
Content-Transfer-Encoding: quoted-printable
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/gen/initgroups.3 ./lib/lib=
c/gen/initgroups.3
--- /usr/fsvn/head/lib/libc/gen/initgroups.3 2009-01-22 10:05:45.000000000 =
-0600
+++ ./lib/libc/gen/initgroups.3 2009-06-09 09:17:36.000000000 -0500
@@ -65,6 +65,13 @@
.Va errno
for any of the errors specified for the library function
.Xr setgroups 2 .
+It may also return:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+The
+.Fn initgroups
+function was unable to allocate temporary storage.
+.El
.Sh SEE ALSO
.Xr setgroups 2 ,
.Xr getgrouplist 3
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/gen/initgroups.c ./lib/lib=
c/gen/initgroups.c
--- /usr/fsvn/head/lib/libc/gen/initgroups.c 2009-01-22 10:05:45.000000000 =
-0600
+++ ./lib/libc/gen/initgroups.c 2009-06-17 14:00:59.000000000 -0500
@@ -35,10 +35,12 @@
=20
#include <sys/param.h>
=20
-#include <stdio.h>
#include "namespace.h"
#include <err.h>
#include "un-namespace.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
=20
int
@@ -46,14 +48,21 @@
const char *uname;
gid_t agroup;
{
- int ngroups;
+ int ngroups, ret;
+ long ngroups_max;
+ gid_t *groups;
+
/*
- * Provide space for one group more than NGROUPS to allow
+ * Provide space for one group more than possible to allow
* setgroups to fail and set errno.
*/
- gid_t groups[NGROUPS + 1];
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 2;
+ if ((groups =3D malloc(sizeof(*groups) * ngroups_max)) =3D=3D NULL)
+ return (ENOMEM);
=20
- ngroups =3D NGROUPS + 1;
+ ngroups =3D (int)ngroups_max;
getgrouplist(uname, agroup, groups, &ngroups);
- return (setgroups(ngroups, groups));
+ ret =3D setgroups(ngroups, groups);
+ free(groups);
+ return (ret);
}
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/rpc/auth_unix.c ./lib/libc=
/rpc/auth_unix.c
--- /usr/fsvn/head/lib/libc/rpc/auth_unix.c 2009-01-22 10:05:43.000000000 -=
0600
+++ ./lib/libc/rpc/auth_unix.c 2009-06-17 14:00:59.000000000 -0500
@@ -185,23 +185,29 @@
AUTH *
authunix_create_default()
{
- int len;
+ int ngids;
+ long ngids_max;
char machname[MAXHOSTNAMELEN + 1];
uid_t uid;
gid_t gid;
- gid_t gids[NGROUPS_MAX];
+ gid_t *gids;
+
+ ngids_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ gids =3D malloc(sizeof(gid_t) * ngids_max);
+ if (gids =3D=3D NULL)
+ return (NULL);
=20
if (gethostname(machname, sizeof machname) =3D=3D -1)
abort();
machname[sizeof(machname) - 1] =3D 0;
uid =3D geteuid();
gid =3D getegid();
- if ((len =3D getgroups(NGROUPS_MAX, gids)) < 0)
+ if ((ngids =3D getgroups(ngids_max, gids)) < 0)
abort();
- if (len > NGRPS)
- len =3D NGRPS;
+ if (ngids > NGRPS)
+ ngids =3D NGRPS;
/* XXX: interface problem; those should all have been unsigned */
- return (authunix_create(machname, (int)uid, (int)gid, len,
+ return (authunix_create(machname, (int)uid, (int)gid, ngids,
(int *)gids));
}
=20
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/sys/getgroups.2 ./lib/libc=
/sys/getgroups.2
--- /usr/fsvn/head/lib/libc/sys/getgroups.2 2009-01-22 10:05:48.000000000 -=
0600
+++ ./lib/libc/sys/getgroups.2 2009-06-16 13:56:17.000000000 -0500
@@ -58,10 +58,7 @@
system call
returns the actual number of groups returned in
.Fa gidset .
-No more than
-.Dv NGROUPS_MAX
-will ever
-be returned.
+At least one and as many as {NGROUPS_MAX}+1 values may be returned.
If
.Fa gidsetlen
is zero,
@@ -92,6 +89,11 @@
.Sh SEE ALSO
.Xr setgroups 2 ,
.Xr initgroups 3
+.Sh STANDARDS
+The
+.Fn getgroups
+system call conforms to
+.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn getgroups
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/sys/setgroups.2 ./lib/libc=
/sys/setgroups.2
--- /usr/fsvn/head/lib/libc/sys/setgroups.2 2009-01-22 10:05:48.000000000 -=
0600
+++ ./lib/libc/sys/setgroups.2 2009-06-16 13:56:17.000000000 -0500
@@ -53,9 +53,7 @@
argument
indicates the number of entries in the array and must be no
more than
-.Dv NGROUPS ,
-as defined in
-.In sys/param.h .
+.Dv {NGROUPS_MAX}+1 .
.Pp
Only the super-user may set a new group list.
.Sh RETURN VALUES
@@ -71,7 +69,7 @@
The number specified in the
.Fa ngroups
argument is larger than the
-.Dv NGROUPS
+.Dv {NGROUPS_MAX}+1
limit.
.It Bq Er EFAULT
The address specified for
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.bin/id/id.c ./usr.bin/id/id.c
--- /usr/fsvn/head/usr.bin/id/id.c 2009-01-22 10:04:13.000000000 -0600
+++ ./usr.bin/id/id.c 2009-06-17 14:00:59.000000000 -0500
@@ -258,7 +258,8 @@
gid_t gid, egid, lastgid;
uid_t uid, euid;
int cnt, ngroups;
- gid_t groups[NGROUPS + 1];
+ long ngroups_max;
+ gid_t *groups;
const char *fmt;
=20
if (pw !=3D NULL) {
@@ -270,12 +271,16 @@
gid =3D getgid();
}
=20
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((groups =3D malloc(sizeof(gid_t) * ngroups_max)) =3D=3D NULL)
+ err(1, "malloc");
+
if (use_ggl && pw !=3D NULL) {
- ngroups =3D NGROUPS + 1;
+ ngroups =3D ngroups_max;
getgrouplist(pw->pw_name, gid, groups, &ngroups);
}
else {
- ngroups =3D getgroups(NGROUPS + 1, groups);
+ ngroups =3D getgroups(ngroups_max, groups);
}
=20
if (pw !=3D NULL)
@@ -306,6 +311,7 @@
lastgid =3D gid;
}
printf("\n");
+ free(groups);
}
=20
#ifdef USE_BSM_AUDIT
@@ -361,15 +367,19 @@
{
struct group *gr;
int cnt, id, lastid, ngroups;
- gid_t groups[NGROUPS + 1];
+ long ngroups_max;
+ gid_t *groups;
const char *fmt;
=20
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((groups =3D malloc(sizeof(gid_t) * (ngroups_max))) =3D=3D NULL)
+ err(1, "malloc");
+
if (pw) {
- ngroups =3D NGROUPS + 1;
+ ngroups =3D ngroups_max;
(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
} else {
- groups[0] =3D getgid();
- ngroups =3D getgroups(NGROUPS, groups + 1) + 1;
+ ngroups =3D getgroups(ngroups_max, groups);
}
fmt =3D nflag ? "%s" : "%u";
for (lastid =3D -1, cnt =3D 0; cnt < ngroups; ++cnt) {
@@ -389,6 +399,7 @@
lastid =3D id;
}
(void)printf("\n");
+ free(groups);
}
=20
void
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.bin/newgrp/newgrp.c ./usr.bin/n=
ewgrp/newgrp.c
--- /usr/fsvn/head/usr.bin/newgrp/newgrp.c 2009-01-22 10:04:11.000000000 -0=
600
+++ ./usr.bin/newgrp/newgrp.c 2009-06-17 14:00:59.000000000 -0500
@@ -146,8 +146,8 @@
static void
addgroup(const char *grpname)
{
- gid_t grps[NGROUPS_MAX];
- long lgid;
+ gid_t *grps;
+ long lgid, ngrps_max;
int dbmember, i, ngrps;
gid_t egid;
struct group *grp;
@@ -185,7 +185,10 @@
}
}
=20
- if ((ngrps =3D getgroups(NGROUPS_MAX, (gid_t *)grps)) < 0) {
+ ngrps_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((grps =3D malloc(sizeof(gid_t) * ngrps_max)) =3D=3D NULL)
+ err(1, "malloc");
+ if ((ngrps =3D getgroups(ngrps_max, (gid_t *)grps)) < 0) {
warn("getgroups");
return;
}
@@ -217,7 +220,7 @@
=20
/* Add old effective gid to supp. list if it does not exist. */
if (egid !=3D grp->gr_gid && !inarray(egid, grps, ngrps)) {
- if (ngrps =3D=3D NGROUPS_MAX)
+ if (ngrps =3D=3D ngrps_max)
warnx("too many groups");
else {
grps[ngrps++] =3D egid;
@@ -231,6 +234,7 @@
}
}
=20
+ free(grps);
}
=20
static int
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.bin/quota/quota.c ./usr.bin/quo=
ta/quota.c
--- /usr/fsvn/head/usr.bin/quota/quota.c 2009-01-22 10:04:12.000000000 -0600
+++ ./usr.bin/quota/quota.c 2009-06-17 14:00:59.000000000 -0500
@@ -117,7 +117,8 @@
main(int argc, char *argv[])
{
int ngroups;=20
- gid_t mygid, gidset[NGROUPS];
+ long ngroups_max;
+ gid_t mygid, *gidset;
int i, ch, gflag =3D 0, uflag =3D 0, errflag =3D 0;
=20
while ((ch =3D getopt(argc, argv, "f:ghlrquv")) !=3D -1) {
@@ -159,13 +160,18 @@
errflag +=3D showuid(getuid());
if (gflag) {
mygid =3D getgid();
- ngroups =3D getgroups(NGROUPS, gidset);
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((gidset =3D malloc(sizeof(gid_t) * ngroups_max))
+ =3D=3D NULL)
+ err(1, "malloc");
+ ngroups =3D getgroups(ngroups_max, gidset);
if (ngroups < 0)
err(1, "getgroups");
errflag +=3D showgid(mygid);
for (i =3D 0; i < ngroups; i++)
if (gidset[i] !=3D mygid)
errflag +=3D showgid(gidset[i]);
+ free(gidset);
}
return(errflag);
}
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/chown/chown.c ./usr.sbin/c=
hown/chown.c
--- /usr/fsvn/head/usr.sbin/chown/chown.c 2009-01-22 10:05:31.000000000 -06=
00
+++ ./usr.sbin/chown/chown.c 2009-06-17 14:00:59.000000000 -0500
@@ -269,7 +269,8 @@
{
static uid_t euid =3D -1;
static int ngroups =3D -1;
- gid_t groups[NGROUPS_MAX];
+ static long ngroups_max;
+ gid_t *groups;
=20
/* Check for chown without being root. */
if (errno !=3D EPERM || (uid !=3D (uid_t)-1 &&
@@ -281,7 +282,10 @@
/* Check group membership; kernel just returns EPERM. */
if (gid !=3D (gid_t)-1 && ngroups =3D=3D -1 &&
euid =3D=3D (uid_t)-1 && (euid =3D geteuid()) !=3D 0) {
- ngroups =3D getgroups(NGROUPS_MAX, groups);
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((groups =3D malloc(sizeof(gid_t) * ngroups_max)) =3D=3D NULL)
+ err(1, "malloc");
+ ngroups =3D getgroups(ngroups_max, groups);
while (--ngroups >=3D 0 && gid !=3D groups[ngroups]);
if (ngroups < 0) {
warnx("you are not a member of group %s", gname);
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/chroot/chroot.c ./usr.sbin=
/chroot/chroot.c
--- /usr/fsvn/head/usr.sbin/chroot/chroot.c 2009-01-22 10:05:34.000000000 -=
0600
+++ ./usr.sbin/chroot/chroot.c 2009-06-17 14:00:59.000000000 -0500
@@ -69,9 +69,10 @@
struct passwd *pw;
char *endp, *p;
const char *shell;
- gid_t gid, gidlist[NGROUPS_MAX];
+ gid_t gid, *gidlist;
uid_t uid;
int ch, gids;
+ long ngroups_max;
=20
gid =3D 0;
uid =3D 0;
@@ -117,8 +118,11 @@
}
}
=20
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((gidlist =3D malloc(sizeof(gid_t) * ngroups_max)) =3D=3D NULL)
+ err(1, "malloc");
for (gids =3D 0;
- (p =3D strsep(&grouplist, ",")) !=3D NULL && gids < NGROUPS_MAX; ) {
+ (p =3D strsep(&grouplist, ",")) !=3D NULL && gids < ngroups_max; ) {
if (*p =3D=3D '\0')
continue;
=20
@@ -135,7 +139,7 @@
}
gids++;
}
- if (p !=3D NULL && gids =3D=3D NGROUPS_MAX)
+ if (p !=3D NULL && gids =3D=3D ngroups_max)
errx(1, "too many supplementary groups provided");
=20
if (user !=3D NULL) {
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/jail/jail.c ./usr.sbin/jai=
l/jail.c
--- /usr/fsvn/head/usr.sbin/jail/jail.c 2009-06-12 00:52:16.000000000 -0500
+++ ./usr.sbin/jail/jail.c 2009-06-17 14:00:59.000000000 -0500
@@ -104,7 +104,7 @@
lcap =3D login_getpwclass(pwd); \
if (lcap =3D=3D NULL) \
err(1, "getpwclass: %s", username); \
- ngroups =3D NGROUPS; \
+ ngroups =3D ngroups_max; \
if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) !=3D 0) \
err(1, "getgrouplist: %s", username); \
} while (0)
@@ -115,10 +115,11 @@
login_cap_t *lcap =3D NULL;
struct iovec rparams[2];
struct passwd *pwd =3D NULL;
- gid_t groups[NGROUPS];
+ gid_t *groups;
size_t sysvallen;
int ch, cmdarg, i, jail_set_flags, jid, ngroups, sysval;
int hflag, iflag, Jflag, lflag, rflag, uflag, Uflag;
+ long ngroups_max;
unsigned pi;
char *ep, *jailname, *securelevel, *username, *JidFile;
char errmsg[ERRMSG_SIZE], enforce_statfs[4];
@@ -132,6 +133,10 @@
jailname =3D securelevel =3D username =3D JidFile =3D cleanenv =3D NULL;
fp =3D NULL;
=20
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;=09
+ if ((groups =3D malloc(sizeof(gid_t) * ngroups_max)) =3D=3D NULL)
+ err(1, "malloc");
+
while ((ch =3D getopt(argc, argv, "cdhilmn:r:s:u:U:J:")) !=3D -1) {
switch (ch) {
case 'd':
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/jexec/jexec.c ./usr.sbin/j=
exec/jexec.c
--- /usr/fsvn/head/usr.sbin/jexec/jexec.c 2009-05-29 12:48:00.000000000 -05=
00
+++ ./usr.sbin/jexec/jexec.c 2009-06-17 14:00:59.000000000 -0500
@@ -59,7 +59,7 @@
lcap =3D login_getpwclass(pwd); \
if (lcap =3D=3D NULL) \
err(1, "getpwclass: %s", username); \
- ngroups =3D NGROUPS; \
+ ngroups =3D ngroups_max; \
if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) !=3D 0) \
err(1, "getgrouplist: %s", username); \
} while (0)
@@ -71,12 +71,17 @@
int jid;
login_cap_t *lcap =3D NULL;
struct passwd *pwd =3D NULL;
- gid_t groups[NGROUPS];
+ gid_t *groups =3D NULL;
int ch, ngroups, uflag, Uflag;
+ long ngroups_max;
char *ep, *username;
ch =3D uflag =3D Uflag =3D 0;
username =3D NULL;
=20
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((groups =3D malloc(sizeof(gid_t) * ngroups_max)) =3D=3D NULL)
+ err(1, "malloc");
+
while ((ch =3D getopt(argc, argv, "nu:U:")) !=3D -1) {
switch (ch) {
case 'n':
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/lpr/lpc/lpc.c ./usr.sbin/l=
pr/lpc/lpc.c
--- /usr/fsvn/head/usr.sbin/lpr/lpc/lpc.c 2009-01-22 10:05:32.000000000 -06=
00
+++ ./usr.sbin/lpr/lpc/lpc.c 2009-06-17 14:00:59.000000000 -0500
@@ -356,7 +356,8 @@
{
static struct group *gptr=3DNULL;
static int ngroups =3D 0;
- static gid_t groups[NGROUPS];
+ static long ngroups_max;
+ static gid_t *groups;
register gid_t gid;
register int i;
=20
@@ -365,7 +366,10 @@
warnx("warning: unknown group '%s'", grname);
return(0);
}
- ngroups =3D getgroups(NGROUPS, groups);
+ ngroups_max =3D sysconf(_SC_NGROUPS_MAX);
+ if ((groups =3D malloc(sizeof(gid_t) * ngroups_max)) =3D=3D NULL)
+ err(1, "malloc");
+ ngroups =3D getgroups(ngroups_max, groups);
if (ngroups < 0)
err(1, "getgroups");
}
--YZ5djTAD1cGYuMQK
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="ngroups-main.diff"
Content-Transfer-Encoding: quoted-printable
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/rpc/netname.c ./lib/libc/r=
pc/netname.c
--- /usr/fsvn/head/lib/libc/rpc/netname.c 2009-01-22 10:05:44.000000000 -06=
00
+++ ./lib/libc/rpc/netname.c 2009-05-14 01:48:22.000000000 -0500
@@ -61,9 +61,6 @@
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
-#ifndef NGROUPS
-#define NGROUPS 16
-#endif
=20
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
=20
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libc/rpc/netnamer.c ./lib/libc/=
rpc/netnamer.c
--- /usr/fsvn/head/lib/libc/rpc/netnamer.c 2009-01-22 10:05:44.000000000 -0=
600
+++ ./lib/libc/rpc/netnamer.c 2009-05-13 22:51:38.000000000 -0500
@@ -66,10 +66,6 @@
static int getnetid( char *, char * );
static int _getgroups( char *, gid_t * );
=20
-#ifndef NGROUPS
-#define NGROUPS 16
-#endif
-
/*
* Convert network-name into unix credential
*/
@@ -104,7 +100,7 @@
return (0);
}
*gidp =3D (gid_t) atol(p);
- for (gidlen =3D 0; gidlen < NGROUPS; gidlen++) {
+ for (gidlen =3D 0; gidlen < NGRPS; gidlen++) {
p =3D strsep(&res, "\n,");
if (p =3D=3D NULL)
break;
@@ -157,7 +153,7 @@
static int
_getgroups(uname, groups)
char *uname;
- gid_t groups[NGROUPS];
+ gid_t groups[NGRPS];
{
gid_t ngroups =3D 0;
struct group *grp;
@@ -169,7 +165,7 @@
while ((grp =3D getgrent())) {
for (i =3D 0; grp->gr_mem[i]; i++)
if (!strcmp(grp->gr_mem[i], uname)) {
- if (ngroups =3D=3D NGROUPS) {
+ if (ngroups =3D=3D NGRPS) {
#ifdef DEBUG
fprintf(stderr,
"initgroups: %s is in too many groups\n", uname);
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/lib/libkvm/kvm_proc.c ./lib/libkvm/=
kvm_proc.c
--- /usr/fsvn/head/lib/libkvm/kvm_proc.c 2009-06-16 15:54:14.000000000 -0500
+++ ./lib/libkvm/kvm_proc.c 2009-05-28 16:40:33.000000000 -0500
@@ -146,8 +146,7 @@
kp->ki_rgid =3D ucred.cr_rgid;
kp->ki_svgid =3D ucred.cr_svgid;
kp->ki_ngroups =3D ucred.cr_ngroups;
- bcopy(ucred.cr_groups, kp->ki_groups,
- NGROUPS * sizeof(gid_t));
+ kp->ki_groups =3D ucred.cr_groups;
kp->ki_uid =3D ucred.cr_uid;
if (ucred.cr_prison !=3D NULL) {
if (KREAD(kd, (u_long)ucred.cr_prison, &pr)) {
Files /usr/fsvn/head/share/examples/kld/firmware/fwimage/firmware.img and .=
/share/examples/kld/firmware/fwimage/firmware.img differ
Only in /usr/fsvn/head/sys: .glimpse_exclude
Only in /usr/fsvn/head/sys: .glimpse_filenames
Only in /usr/fsvn/head/sys: .glimpse_filenames_index
Only in /usr/fsvn/head/sys: .glimpse_filetimes
Only in /usr/fsvn/head/sys: .glimpse_index
Only in /usr/fsvn/head/sys: .glimpse_messages
Only in /usr/fsvn/head/sys: .glimpse_partitions
Only in /usr/fsvn/head/sys: .glimpse_statistics
Only in /usr/fsvn/head/sys: .glimpse_turbo
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/compat/linux/linux_misc.c ./sys=
/compat/linux/linux_misc.c
--- /usr/fsvn/head/sys/compat/linux/linux_misc.c 2009-06-16 15:54:53.000000=
000 -0500
+++ ./sys/compat/linux/linux_misc.c 2009-06-16 13:56:19.000000000 -0500
@@ -1132,7 +1132,7 @@
linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
{
struct ucred *newcred, *oldcred;
- l_gid_t linux_gidset[NGROUPS];
+ l_gid_t *linux_gidset;
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
@@ -1140,13 +1140,14 @@
ngrp =3D args->gidsetsize;
if (ngrp < 0 || ngrp >=3D NGROUPS)
return (EINVAL);
+ linux_gidset =3D malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error =3D copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
if (error)
- return (error);
+ goto out;
newcred =3D crget();
p =3D td->td_proc;
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
/*
* cr_groups[0] holds egid. Setting the whole set from
@@ -1157,10 +1158,9 @@
if ((error =3D priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) !=3D 0) {
PROC_UNLOCK(p);
crfree(newcred);
- return (error);
+ goto out;
}
=20
- crcopy(newcred, oldcred);
if (ngrp > 0) {
newcred->cr_ngroups =3D ngrp + 1;
=20
@@ -1177,14 +1177,17 @@
p->p_ucred =3D newcred;
PROC_UNLOCK(p);
crfree(oldcred);
- return (0);
+ error =3D 0;
+out:
+ free(linux_gidset, M_TEMP);
+ return (error);
}
=20
int
linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
{
struct ucred *cred;
- l_gid_t linux_gidset[NGROUPS];
+ l_gid_t *linux_gidset;
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
=20
@@ -1207,13 +1210,16 @@
return (EINVAL);
=20
ngrp =3D 0;
+ linux_gidset =3D malloc(bsd_gidsetsz * sizeof(*linux_gidset),
+ M_TEMP, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] =3D bsd_gidset[ngrp + 1];
ngrp++;
}
=20
- if ((error =3D copyout(linux_gidset, args->grouplist,
- ngrp * sizeof(l_gid_t))))
+ error =3D copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t));
+ free(linux_gidset, M_TEMP);
+ if (error)
return (error);
=20
td->td_retval[0] =3D ngrp;
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/compat/linux/linux_uid16.c ./sy=
s/compat/linux/linux_uid16.c
--- /usr/fsvn/head/sys/compat/linux/linux_uid16.c 2009-06-16 15:54:53.00000=
0000 -0500
+++ ./sys/compat/linux/linux_uid16.c 2009-05-28 16:40:33.000000000 -0500
@@ -98,7 +98,7 @@
linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
{
struct ucred *newcred, *oldcred;
- l_gid16_t linux_gidset[NGROUPS];
+ l_gid16_t *linux_gidset;
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
@@ -111,13 +111,14 @@
ngrp =3D args->gidsetsize;
if (ngrp < 0 || ngrp >=3D NGROUPS)
return (EINVAL);
+ linux_gidset =3D malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error =3D copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
if (error)
return (error);
newcred =3D crget();
p =3D td->td_proc;
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
/*
* cr_groups[0] holds egid. Setting the whole set from
@@ -128,10 +129,9 @@
if ((error =3D priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) !=3D 0) {
PROC_UNLOCK(p);
crfree(newcred);
- return (error);
+ goto out;
}
=20
- crcopy(newcred, oldcred);
if (ngrp > 0) {
newcred->cr_ngroups =3D ngrp + 1;
=20
@@ -149,14 +149,17 @@
p->p_ucred =3D newcred;
PROC_UNLOCK(p);
crfree(oldcred);
- return (0);
+ error =3D 0;
+out:
+ free(linux_gidset, M_TEMP);
+ return (error);
}
=20
int
linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
{
struct ucred *cred;
- l_gid16_t linux_gidset[NGROUPS];
+ l_gid16_t *linux_gidset;
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
=20
@@ -184,12 +187,15 @@
return (EINVAL);
=20
ngrp =3D 0;
+ linux_gidset =3D malloc(bsd_gidsetsz * sizeof(*linux_gidset),
+ M_TEMP, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] =3D bsd_gidset[ngrp + 1];
ngrp++;
}
=20
error =3D copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
+ free(linux_gidset, M_TEMP);
if (error)
return (error);
=20
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/nfs/nfs_commonport.c ./sys/f=
s/nfs/nfs_commonport.c
--- /usr/fsvn/head/sys/fs/nfs/nfs_commonport.c 2009-05-29 12:48:03.00000000=
0 -0500
+++ ./sys/fs/nfs/nfs_commonport.c 2009-06-09 08:49:37.000000000 -0500
@@ -220,14 +220,9 @@
void
newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
{
- int ngroups, i;
=20
cr->cr_uid =3D nfscr->nfsc_uid;
- ngroups =3D (nfscr->nfsc_ngroups < NGROUPS) ?
- nfscr->nfsc_ngroups : NGROUPS;
- for (i =3D 0; i < ngroups; i++)
- cr->cr_groups[i] =3D nfscr->nfsc_groups[i];
- cr->cr_ngroups =3D ngroups;
+ crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
}
=20
/*
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/nfsclient/nfs_clport.c ./sys=
/fs/nfsclient/nfs_clport.c
--- /usr/fsvn/head/sys/fs/nfsclient/nfs_clport.c 2009-05-29 12:48:03.000000=
000 -0500
+++ ./sys/fs/nfsclient/nfs_clport.c 2009-06-05 15:33:54.000000000 -0500
@@ -976,14 +976,12 @@
void
newnfs_copyincred(struct ucred *cr, struct nfscred *nfscr)
{
- int ngroups, i;
+ int i;
=20
nfscr->nfsc_uid =3D cr->cr_uid;
- ngroups =3D (cr->cr_ngroups > NGROUPS) ? NGROUPS :
- cr->cr_ngroups;
- for (i =3D 0; i < ngroups; i++)
+ nfscr->nfsc_ngroups =3D MIN(cr->cr_ngroups, XU_NGROUPS);
+ for (i =3D 0; i < nfscr->nfsc_ngroups; i++)
nfscr->nfsc_groups[i] =3D cr->cr_groups[i];
- nfscr->nfsc_ngroups =3D ngroups;
}
=20
=20
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/nfsserver/nfs_nfsdport.c ./s=
ys/fs/nfsserver/nfs_nfsdport.c
--- /usr/fsvn/head/sys/fs/nfsserver/nfs_nfsdport.c 2009-06-05 15:33:50.0000=
00000 -0500
+++ ./sys/fs/nfsserver/nfs_nfsdport.c 2009-06-05 16:02:29.000000000 -0500
@@ -2360,7 +2360,6 @@
nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
struct ucred *credanon)
{
- int i;
int error =3D 0;
=20
/*
@@ -2403,9 +2402,8 @@
(nd->nd_flag & ND_AUTHNONE))) {
nd->nd_cred->cr_uid =3D credanon->cr_uid;
nd->nd_cred->cr_gid =3D credanon->cr_gid;
- for (i =3D 0; i < credanon->cr_ngroups && i < NGROUPS; i++)
- nd->nd_cred->cr_groups[i] =3D credanon->cr_groups[i];
- nd->nd_cred->cr_ngroups =3D i;
+ crsetgroups(nd->nd_cred, credanon->cr_ngroups,
+ credanon->cr_groups);
}
return (0);
}
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/nfsserver/nfs_nfsdstate.c ./=
sys/fs/nfsserver/nfs_nfsdstate.c
--- /usr/fsvn/head/sys/fs/nfsserver/nfs_nfsdstate.c 2009-06-16 13:55:57.000=
000000 -0500
+++ ./sys/fs/nfsserver/nfs_nfsdstate.c 2009-06-16 13:56:18.000000000 -0500
@@ -3577,7 +3577,6 @@
nd->nd_repstat =3D 0;
cred->cr_uid =3D clp->lc_uid;
cred->cr_gid =3D clp->lc_gid;
- cred->cr_groups[0] =3D clp->lc_gid;
callback =3D clp->lc_callback;
NFSUNLOCKSTATE();
cred->cr_ngroups =3D 1;
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/portalfs/portal.h ./sys/fs/p=
ortalfs/portal.h
--- /usr/fsvn/head/sys/fs/portalfs/portal.h 2009-01-22 10:06:01.000000000 -=
0600
+++ ./sys/fs/portalfs/portal.h 2009-06-05 15:33:54.000000000 -0500
@@ -43,7 +43,7 @@
int pcr_flag; /* File open mode */
uid_t pcr_uid; /* From ucred */
short pcr_ngroups; /* From ucred */
- gid_t pcr_groups[NGROUPS]; /* From ucred */
+ gid_t pcr_groups[XU_NGROUPS]; /* From ucred */
};
=20
#ifdef _KERNEL
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/portalfs/portal_vnops.c ./sy=
s/fs/portalfs/portal_vnops.c
--- /usr/fsvn/head/sys/fs/portalfs/portal_vnops.c 2009-01-22 10:06:01.00000=
0000 -0600
+++ ./sys/fs/portalfs/portal_vnops.c 2009-06-05 15:33:54.000000000 -0500
@@ -311,8 +311,9 @@
=20
pcred.pcr_flag =3D ap->a_mode;
pcred.pcr_uid =3D ap->a_cred->cr_uid;
- pcred.pcr_ngroups =3D ap->a_cred->cr_ngroups;
- bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t));
+ pcred.pcr_ngroups =3D MIN(ap->a_cred->cr_ngroups, XU_NGROUPS);
+ bcopy(ap->a_cred->cr_groups, pcred.pcr_groups,
+ pcred.pcr_ngroups * sizeof(gid_t));
aiov[0].iov_base =3D (caddr_t) &pcred;
aiov[0].iov_len =3D sizeof(pcred);
aiov[1].iov_base =3D pt->pt_arg;
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/fs/unionfs/union_vnops.c ./sys/=
fs/unionfs/union_vnops.c
--- /usr/fsvn/head/sys/fs/unionfs/union_vnops.c 2009-04-12 15:26:52.0000000=
00 -0500
+++ ./sys/fs/unionfs/union_vnops.c 2009-06-05 15:33:54.000000000 -0500
@@ -638,7 +638,6 @@
uid_t uid; /* upper side vnode's uid */
gid_t gid; /* upper side vnode's gid */
u_short vmode; /* upper side vnode's mode */
- gid_t *gp;
u_short mask;
=20
mask =3D 0;
@@ -659,17 +658,14 @@
=20
/* check group */
count =3D 0;
- gp =3D cred->cr_groups;
- for (; count < cred->cr_ngroups; count++, gp++) {
- if (gid =3D=3D *gp) {
- if (accmode & VEXEC)
- mask |=3D S_IXGRP;
- if (accmode & VREAD)
- mask |=3D S_IRGRP;
- if (accmode & VWRITE)
- mask |=3D S_IWGRP;
- return ((vmode & mask) =3D=3D mask ? 0 : EACCES);
- }
+ if (groupmember(gid, cred)) {
+ if (accmode & VEXEC)
+ mask |=3D S_IXGRP;
+ if (accmode & VREAD)
+ mask |=3D S_IRGRP;
+ if (accmode & VWRITE)
+ mask |=3D S_IWGRP;
+ return ((vmode & mask) =3D=3D mask ? 0 : EACCES);
}
=20
/* check other */
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/i386/ibcs2/ibcs2_misc.c ./sys/i=
386/ibcs2/ibcs2_misc.c
--- /usr/fsvn/head/sys/i386/ibcs2/ibcs2_misc.c 2009-06-16 15:54:53.00000000=
0 -0500
+++ ./sys/i386/ibcs2/ibcs2_misc.c 2009-06-05 16:02:31.000000000 -0500
@@ -657,24 +657,29 @@
struct thread *td;
struct ibcs2_getgroups_args *uap;
{
- ibcs2_gid_t iset[NGROUPS_MAX];
- gid_t gp[NGROUPS_MAX];
+ ibcs2_gid_t *iset;
+ gid_t *gp;
u_int i, ngrp;
int error;
=20
if (uap->gidsetsize < 0)
return (EINVAL);
ngrp =3D MIN(uap->gidsetsize, NGROUPS_MAX);
+ gp =3D malloc(ngrp * sizeof(*gp), M_TEMP, M_WAITOK);
error =3D kern_getgroups(td, &ngrp, gp);
if (error)
- return (error);
+ goto out;
if (uap->gidsetsize > 0) {
+ iset =3D malloc(ngrp * sizeof(*iset), M_TEMP, M_WAITOK);
for (i =3D 0; i < ngrp; i++)
iset[i] =3D (ibcs2_gid_t)gp[i];
error =3D copyout(iset, uap->gidset, ngrp * sizeof(ibcs2_gid_t));
+ free(iset, M_TEMP);
}
if (error =3D=3D 0)
td->td_retval[0] =3D ngrp;
+out:
+ free(gp, M_TEMP);
return (error);
}
=20
@@ -683,21 +688,31 @@
struct thread *td;
struct ibcs2_setgroups_args *uap;
{
- ibcs2_gid_t iset[NGROUPS_MAX];
- gid_t gp[NGROUPS_MAX];
+ ibcs2_gid_t *iset;
+ gid_t *gp;
int error, i;
=20
if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS_MAX)
return (EINVAL);
- if (uap->gidsetsize && uap->gidset) {
+ if (uap->gidsetsize && uap->gidset =3D=3D NULL)
+ return (EINVAL);
+ gp =3D malloc(uap->gidsetsize * sizeof(*gp), M_TEMP, M_WAITOK);
+ if (uap->gidsetsize) {
+ iset =3D malloc(uap->gidsetsize * sizeof(*iset), M_TEMP, M_WAITOK);
error =3D copyin(uap->gidset, iset, sizeof(ibcs2_gid_t) *
uap->gidsetsize);
- if (error)
- return (error);
+ if (error) {
+ free(iset, M_TEMP);
+ goto out;
+ }
for (i =3D 0; i < uap->gidsetsize; i++)
gp[i] =3D (gid_t)iset[i];
}
- return (kern_setgroups(td, uap->gidsetsize, gp));
+
+ error =3D kern_setgroups(td, uap->gidsetsize, gp);
+out:
+ free(gp, M_TEMP);
+ return (error);
}
=20
int
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/kern/kern_exec.c ./sys/kern/ker=
n_exec.c
--- /usr/fsvn/head/sys/kern/kern_exec.c 2009-06-16 15:54:34.000000000 -0500
+++ ./sys/kern/kern_exec.c 2009-06-12 01:13:11.000000000 -0500
@@ -579,6 +579,7 @@
* reset.
*/
PROC_LOCK(p);
+ oldcred =3D crcopysafe(p, newcred);
if (sigacts_shared(p->p_sigacts)) {
oldsigacts =3D p->p_sigacts;
PROC_UNLOCK(p);
@@ -629,7 +630,6 @@
* XXXMAC: For the time being, use NOSUID to also prohibit
* transitions on the file system.
*/
- oldcred =3D p->p_ucred;
credential_changing =3D 0;
credential_changing |=3D (attr.va_mode & S_ISUID) && oldcred->cr_uid !=3D
attr.va_uid;
@@ -683,7 +683,6 @@
/*
* Set the new credentials.
*/
- crcopy(newcred, oldcred);
if (attr.va_mode & S_ISUID)
change_euid(newcred, euip);
if (attr.va_mode & S_ISGID)
@@ -723,7 +722,6 @@
*/
if (oldcred->cr_svuid !=3D oldcred->cr_uid ||
oldcred->cr_svgid !=3D oldcred->cr_gid) {
- crcopy(newcred, oldcred);
change_svuid(newcred, newcred->cr_uid);
change_svgid(newcred, newcred->cr_gid);
p->p_ucred =3D newcred;
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/kern/kern_proc.c ./sys/kern/ker=
n_proc.c
--- /usr/fsvn/head/sys/kern/kern_proc.c 2009-06-16 15:54:34.000000000 -0500
+++ ./sys/kern/kern_proc.c 2009-06-05 16:02:28.000000000 -0500
@@ -730,10 +730,8 @@
kp->ki_uid =3D cred->cr_uid;
kp->ki_ruid =3D cred->cr_ruid;
kp->ki_svuid =3D cred->cr_svuid;
- /* XXX bde doesn't like KI_NGROUPS */
- kp->ki_ngroups =3D min(cred->cr_ngroups, KI_NGROUPS);
- bcopy(cred->cr_groups, kp->ki_groups,
- kp->ki_ngroups * sizeof(gid_t));
+ kp->ki_ngroups =3D cred->cr_ngroups;
+ kp->ki_groups =3D cred->cr_groups;
kp->ki_rgid =3D cred->cr_rgid;
kp->ki_svgid =3D cred->cr_svgid;
kp->ki_cr_flags =3D cred->cr_flags;
--- /usr/fsvn/head/sys/kern/kern_prot.c 2009-06-16 15:54:34.000000000 -0500
+++ ./sys/kern/kern_prot.c 2009-06-17 18:24:56.000000000 -0500
@@ -82,6 +82,10 @@
=20
SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy"=
);
=20
+static void crextend(struct ucred *cr, int n);
+static void crsetgroups_locked(struct ucred *cr, int ngrp,
+ gid_t *groups);
+
#ifndef _SYS_SYSPROTO_H_
struct getpid_args {
int dummy;
@@ -276,18 +280,21 @@
int
getgroups(struct thread *td, register struct getgroups_args *uap)
{
- gid_t groups[NGROUPS];
+ gid_t *groups;
u_int ngrp;
int error;
=20
ngrp =3D MIN(uap->gidsetsize, NGROUPS);
+ groups =3D malloc(ngrp * sizeof(*groups), M_TEMP, M_WAITOK);
error =3D kern_getgroups(td, &ngrp, groups);
if (error)
- return (error);
+ goto out;
if (uap->gidsetsize > 0)
error =3D copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
if (error =3D=3D 0)
td->td_retval[0] =3D ngrp;
+out:
+ free(groups, M_TEMP);
return (error);
}
=20
@@ -486,7 +493,10 @@
newcred =3D crget();
uip =3D uifind(uid);
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ /*
+ * Copy credentials so other references do not see our changes.
+ */
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setuid(oldcred, uid);
@@ -521,10 +531,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)) !=3D 0)
goto fail;
=20
- /*
- * Copy credentials so other references do not see our changes.
- */
- crcopy(newcred, oldcred);
#ifdef _POSIX_SAVED_IDS
/*
* Do we have "appropriate privileges" (are we root or uid =3D=3D euid)
@@ -598,7 +604,10 @@
newcred =3D crget();
euip =3D uifind(euid);
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ /*
+ * Copy credentials so other references do not see our changes.
+ */
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_seteuid(oldcred, euid);
@@ -612,8 +621,7 @@
goto fail;
=20
/*
- * Everything's okay, do it. Copy credentials so other references do
- * not see our changes.
+ * Everything's okay, do it.
*/
crcopy(newcred, oldcred);
if (oldcred->cr_uid !=3D euid) {
@@ -651,7 +659,7 @@
AUDIT_ARG(gid, gid);
newcred =3D crget();
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setgid(oldcred, gid);
@@ -680,7 +688,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETGID, 0)) !=3D 0)
goto fail;
=20
- crcopy(newcred, oldcred);
#ifdef _POSIX_SAVED_IDS
/*
* Do we have "appropriate privileges" (are we root or gid =3D=3D egid)
@@ -750,7 +757,7 @@
AUDIT_ARG(egid, egid);
newcred =3D crget();
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setegid(oldcred, egid);
@@ -763,7 +770,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETEGID, 0)) !=3D 0)
goto fail;
=20
- crcopy(newcred, oldcred);
if (oldcred->cr_groups[0] !=3D egid) {
change_egid(newcred, egid);
setsugid(p);
@@ -789,15 +795,19 @@
int
setgroups(struct thread *td, struct setgroups_args *uap)
{
- gid_t groups[NGROUPS];
+ gid_t *groups =3D NULL;
int error;
=20
if (uap->gidsetsize > NGROUPS)
return (EINVAL);
+ groups =3D malloc(uap->gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK);
error =3D copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t));
if (error)
- return (error);
- return (kern_setgroups(td, uap->gidsetsize, groups));
+ goto out;
+ error =3D kern_setgroups(td, uap->gidsetsize, groups);
+out:
+ free(groups, M_TEMP);
+ return (error);
}
=20
int
@@ -811,8 +821,9 @@
return (EINVAL);
AUDIT_ARG(groupset, groups, ngrp);
newcred =3D crget();
+ crextend(newcred, ngrp);
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setgroups(oldcred, ngrp, groups);
@@ -824,11 +835,6 @@
if (error)
goto fail;
=20
- /*
- * XXX A little bit lazy here. We could test if anything has
- * changed before crcopy() and setting P_SUGID.
- */
- crcopy(newcred, oldcred);
if (ngrp < 1) {
/*
* setgroups(0, NULL) is a legitimate way of clearing the
@@ -838,8 +844,7 @@
*/
newcred->cr_ngroups =3D 1;
} else {
- bcopy(groups, newcred->cr_groups, ngrp * sizeof(gid_t));
- newcred->cr_ngroups =3D ngrp;
+ crsetgroups_locked(newcred, ngrp, groups);
}
setsugid(p);
p->p_ucred =3D newcred;
@@ -877,7 +882,7 @@
euip =3D uifind(euid);
ruip =3D uifind(ruid);
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setreuid(oldcred, ruid, euid);
@@ -892,7 +897,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETREUID, 0)) !=3D 0)
goto fail;
=20
- crcopy(newcred, oldcred);
if (euid !=3D (uid_t)-1 && oldcred->cr_uid !=3D euid) {
change_euid(newcred, euip);
setsugid(p);
@@ -942,7 +946,7 @@
AUDIT_ARG(rgid, rgid);
newcred =3D crget();
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setregid(oldcred, rgid, egid);
@@ -957,7 +961,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETREGID, 0)) !=3D 0)
goto fail;
=20
- crcopy(newcred, oldcred);
if (egid !=3D (gid_t)-1 && oldcred->cr_groups[0] !=3D egid) {
change_egid(newcred, egid);
setsugid(p);
@@ -1013,7 +1016,7 @@
euip =3D uifind(euid);
ruip =3D uifind(ruid);
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setresuid(oldcred, ruid, euid, suid);
@@ -1033,7 +1036,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETRESUID, 0)) !=3D 0)
goto fail;
=20
- crcopy(newcred, oldcred);
if (euid !=3D (uid_t)-1 && oldcred->cr_uid !=3D euid) {
change_euid(newcred, euip);
setsugid(p);
@@ -1090,7 +1092,7 @@
AUDIT_ARG(sgid, sgid);
newcred =3D crget();
PROC_LOCK(p);
- oldcred =3D p->p_ucred;
+ oldcred =3D crcopysafe(p, newcred);
=20
#ifdef MAC
error =3D mac_cred_check_setresgid(oldcred, rgid, egid, sgid);
@@ -1110,7 +1112,6 @@
(error =3D priv_check_cred(oldcred, PRIV_CRED_SETRESGID, 0)) !=3D 0)
goto fail;
=20
- crcopy(newcred, oldcred);
if (egid !=3D (gid_t)-1 && oldcred->cr_groups[0] !=3D egid) {
change_egid(newcred, egid);
setsugid(p);
@@ -1780,6 +1781,7 @@
#ifdef MAC
mac_cred_init(cr);
#endif
+ crextend(cr, XU_NGROUPS);
return (cr);
}
=20
@@ -1829,6 +1831,7 @@
#ifdef MAC
mac_cred_destroy(cr);
#endif
+ free(cr->cr_groups, M_CRED);
free(cr, M_CRED);
}
}
@@ -1854,6 +1857,7 @@
bcopy(&src->cr_startcopy, &dest->cr_startcopy,
(unsigned)((caddr_t)&src->cr_endcopy -
(caddr_t)&src->cr_startcopy));
+ crsetgroups(dest, src->cr_ngroups, src->cr_groups);
uihold(dest->cr_uidinfo);
uihold(dest->cr_ruidinfo);
prison_hold(dest->cr_prison);
@@ -1888,12 +1892,16 @@
void
cru2x(struct ucred *cr, struct xucred *xcr)
{
+ int ngroups;
=20
bzero(xcr, sizeof(*xcr));
xcr->cr_version =3D XUCRED_VERSION;
xcr->cr_uid =3D cr->cr_uid;
- xcr->cr_ngroups =3D cr->cr_ngroups;
- bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
+
+ ngroups =3D MIN(cr->cr_ngroups, XU_NGROUPS);
+ xcr->cr_ngroups =3D ngroups;
+ bcopy(cr->cr_groups, xcr->cr_groups,
+ ngroups * sizeof(*cr->cr_groups));
}
=20
/*
@@ -1915,6 +1923,97 @@
crfree(cred);
}
=20
+struct ucred *
+crcopysafe(struct proc *p, struct ucred *cr)
+{
+ struct ucred *oldcred;
+ int groups;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ oldcred =3D p->p_ucred;
+ while (cr->cr_agroups < oldcred->cr_agroups) {
+ groups =3D oldcred->cr_agroups;
+ PROC_UNLOCK(p);
+ crextend(cr, groups);
+ PROC_LOCK(p);
+ oldcred =3D p->p_ucred;
+ }
+ crcopy(cr, oldcred);
+
+ return (oldcred);
+}
+
+/*
+ * Extend the passed in credential to hold n items.
+ */
+static void
+crextend(struct ucred *cr, int n)
+{
+ int cnt;
+
+ /* Truncate? */
+ if (n <=3D cr->cr_agroups)
+ return;
+
+ /*
+ * We extend by 2 each time since we're using a power of two
+ * allocator until we need enough groups to fill a page.
+ * Once we're allocating multiple pages, only allocate as many
+ * as we actually need. The case of processes needing a
+ * non-power of two number of pages seems more likely than
+ * a real world process that adds thousands of groups one at a
+ * time.
+ */
+ if ( n < PAGE_SIZE / sizeof(gid_t) ) {
+ if (cr->cr_agroups =3D=3D 0)
+ cnt =3D MINALLOCSIZE / sizeof(gid_t);
+ else
+ cnt =3D cr->cr_agroups * 2;
+
+ while (cnt < n)
+ cnt *=3D 2;
+ } else
+ cnt =3D roundup2(n, PAGE_SIZE / sizeof(gid_t));
+
+ /* Free the old array. */
+ if (cr->cr_groups)
+ free(cr->cr_groups, M_CRED);
+
+ cr->cr_groups =3D malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO);
+ cr->cr_agroups =3D cnt;
+}
+
+/*
+ * Copy groups in to a credential, preserving any necessicary invariants
+ * (i.e. sorting in the future). crextend() must have been called
+ * before hand to ensure sufficient space is available. If=20
+ */
+static void
+crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
+{
+=09
+ KASSERT(cr->cr_agroups >=3D ngrp, ("cr_ngroups is too small"));
+
+ bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t));
+ cr->cr_ngroups =3D ngrp;
+}
+
+/*
+ * Copy groups in to a credential after expanding it if required.
+ * Truncate the list to NGROUPS if it is too large.
+ */
+void
+crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
+{
+
+ if (ngrp > NGROUPS)
+ ngrp =3D NGROUPS;
+
+ crextend(cr, ngrp);
+ crsetgroups_locked(cr, ngrp, groups);
+}
+
/*
* Get login name, if available.
*/
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/kern/vfs_export.c ./sys/kern/vf=
s_export.c
--- /usr/fsvn/head/sys/kern/vfs_export.c 2009-05-29 12:48:02.000000000 -0500
+++ ./sys/kern/vfs_export.c 2009-06-05 15:33:54.000000000 -0500
@@ -120,9 +120,8 @@
np->netc_exflags =3D argp->ex_flags;
np->netc_anon =3D crget();
np->netc_anon->cr_uid =3D argp->ex_anon.cr_uid;
- np->netc_anon->cr_ngroups =3D argp->ex_anon.cr_ngroups;
- bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups,
- sizeof(np->netc_anon->cr_groups));
+ crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
+ argp->ex_anon.cr_groups);
np->netc_numsecflavors =3D argp->ex_numsecflavors;
bcopy(argp->ex_secflavors, np->netc_secflavors,
sizeof(np->netc_secflavors));
@@ -205,9 +204,8 @@
np->netc_exflags =3D argp->ex_flags;
np->netc_anon =3D crget();
np->netc_anon->cr_uid =3D argp->ex_anon.cr_uid;
- np->netc_anon->cr_ngroups =3D argp->ex_anon.cr_ngroups;
- bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups,
- sizeof(np->netc_anon->cr_groups));
+ crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
+ np->netc_anon->cr_groups);
np->netc_numsecflavors =3D argp->ex_numsecflavors;
bcopy(argp->ex_secflavors, np->netc_secflavors,
sizeof(np->netc_secflavors));
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/netinet/ipfw/ip_fw2.c ./sys/net=
inet/ipfw/ip_fw2.c
--- /usr/fsvn/head/sys/netinet/ipfw/ip_fw2.c 2009-06-12 00:52:26.000000000 =
-0500
+++ ./sys/netinet/ipfw/ip_fw2.c 2009-06-17 13:42:23.000000000 -0500
@@ -135,19 +135,6 @@
struct ip_fw *ip_fw_default_rule;
=20
/*
- * Data structure to cache our ucred related
- * information. This structure only gets used if
- * the user specified UID/GID based constraints in
- * a firewall rule.
- */
-struct ip_fw_ugid {
- gid_t fw_groups[NGROUPS];
- int fw_ngroups;
- uid_t fw_uid;
- int fw_prid;
-};
-
-/*
* list of rules for layer 3
*/
#ifdef VIMAGE_GLOBALS
@@ -2009,22 +1996,10 @@
return (0);
}
=20
-static void
-fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
-{
- struct ucred *cr;
-
- cr =3D inp->inp_cred;
- ugp->fw_prid =3D jailed(cr) ? cr->cr_prison->pr_id : -1;
- ugp->fw_uid =3D cr->cr_uid;
- ugp->fw_ngroups =3D cr->cr_ngroups;
- bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
-}
-
static int
check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
- u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
+ u_int16_t src_port, struct ucred **uc, int *ugid_lookupp,
struct inpcb *inp)
{
INIT_VNET_INET(curvnet);
@@ -2032,7 +2007,6 @@
int wildcard;
struct inpcb *pcb;
int match;
- gid_t *gp;
=20
/*
* Check to see if the UDP or TCP stack supplied us with
@@ -2042,7 +2016,7 @@
if (inp && *ugid_lookupp =3D=3D 0) {
INP_LOCK_ASSERT(inp);
if (inp->inp_socket !=3D NULL) {
- fill_ugid_cache(inp, ugp);
+ *uc =3D crhold(inp->inp_cred);
*ugid_lookupp =3D 1;
} else
*ugid_lookupp =3D -1;
@@ -2075,7 +2049,7 @@
dst_ip, htons(dst_port),
wildcard, NULL);
if (pcb !=3D NULL) {
- fill_ugid_cache(pcb, ugp);
+ *uc =3D crhold(inp->inp_cred);
*ugid_lookupp =3D 1;
}
INP_INFO_RUNLOCK(pi);
@@ -2091,16 +2065,11 @@
}
}=20
if (insn->o.opcode =3D=3D O_UID)
- match =3D (ugp->fw_uid =3D=3D (uid_t)insn->d[0]);
- else if (insn->o.opcode =3D=3D O_GID) {
- for (gp =3D ugp->fw_groups;
- gp < &ugp->fw_groups[ugp->fw_ngroups]; gp++)
- if (*gp =3D=3D (gid_t)insn->d[0]) {
- match =3D 1;
- break;
- }
- } else if (insn->o.opcode =3D=3D O_JAIL)
- match =3D (ugp->fw_prid =3D=3D (int)insn->d[0]);
+ match =3D ((*uc)->cr_uid =3D=3D (uid_t)insn->d[0]);
+ else if (insn->o.opcode =3D=3D O_GID)
+ match =3D groupmember((gid_t)insn->d[0], *uc);
+ else if (insn->o.opcode =3D=3D O_JAIL)
+ match =3D ((*uc)->cr_prison->pr_id =3D=3D (int)insn->d[0]);
return match;
}
=20
@@ -2178,8 +2147,8 @@
* these types of constraints, as well as decrease contention
* on pcb related locks.
*/
- struct ip_fw_ugid fw_ugid_cache;
- int ugid_lookup =3D 0;
+ struct ucred *ucred_cache =3D NULL;
+ int ucred_lookup =3D 0;
=20
/*
* divinput_flags If non-zero, set to the IP_FW_DIVERT_*_FLAG
@@ -2641,8 +2610,8 @@
(ipfw_insn_u32 *)cmd,
proto, oif,
dst_ip, dst_port,
- src_ip, src_port, &fw_ugid_cache,
- &ugid_lookup, args->inp);
+ src_ip, src_port, &ucred_cache,
+ &ucred_lookup, args->inp);
break;
=20
case O_RECV:
@@ -3270,6 +3239,8 @@
/* XXX statistic */
/* drop packet */
IPFW_RUNLOCK(chain);
+ if (ucred_cache !=3D NULL)
+ crfree(ucred_cache);
return (IP_FW_DENY);
}
dt =3D (struct divert_tag *)(mtag+1);
@@ -3475,6 +3446,8 @@
} /* end of outer for, scan rules */
printf("ipfw: ouch!, skip past end of rules, denying packet\n");
IPFW_RUNLOCK(chain);
+ if (ucred_cache !=3D NULL)
+ crfree(ucred_cache);
return (IP_FW_DENY);
=20
done:
@@ -3483,6 +3456,8 @@
f->bcnt +=3D pktlen;
f->timestamp =3D time_uptime;
IPFW_RUNLOCK(chain);
+ if (ucred_cache !=3D NULL)
+ crfree(ucred_cache);
return (retval);
=20
pullup_failed:
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/nfsserver/nfs_srvsock.c ./sys/n=
fsserver/nfs_srvsock.c
--- /usr/fsvn/head/sys/nfsserver/nfs_srvsock.c 2009-06-16 15:54:40.00000000=
0 -0500
+++ ./sys/nfsserver/nfs_srvsock.c 2009-06-09 08:49:37.000000000 -0500
@@ -370,11 +370,11 @@
}
tl =3D nfsm_dissect_nonblock(u_int32_t *, (len + 2) * NFSX_UNSIGNED);
for (i =3D 1; i <=3D len; i++)
- if (i < NGROUPS)
+ if (i < XU_NGROUPS)
nd->nd_cr->cr_groups[i] =3D fxdr_unsigned(gid_t, *tl++);
else
tl++;
- nd->nd_cr->cr_ngroups =3D (len >=3D NGROUPS) ? NGROUPS : (len + 1);
+ nd->nd_cr->cr_ngroups =3D MIN(XU_NGROUPS, len + 1);
if (nd->nd_cr->cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr->cr_groups, nd->nd_cr->cr_ngroups);
len =3D fxdr_unsigned(int, *++tl);
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/nfsserver/nfs_srvsubs.c ./sys/n=
fsserver/nfs_srvsubs.c
--- /usr/fsvn/head/sys/nfsserver/nfs_srvsubs.c 2009-05-29 12:48:04.00000000=
0 -0500
+++ ./sys/nfsserver/nfs_srvsubs.c 2009-06-05 15:33:54.000000000 -0500
@@ -1181,9 +1181,7 @@
cred =3D nfsd->nd_cr;
if (cred->cr_uid =3D=3D 0 || (exflags & MNT_EXPORTANON)) {
cred->cr_uid =3D credanon->cr_uid;
- for (i =3D 0; i < credanon->cr_ngroups && i < NGROUPS; i++)
- cred->cr_groups[i] =3D credanon->cr_groups[i];
- cred->cr_ngroups =3D i;
+ crsetgroups(cred, credanon->cr_ngroups, credanon->cr_groups);
}
if (exflags & MNT_EXRDONLY)
*rdonlyp =3D 1;
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c=
./sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
--- /usr/fsvn/head/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c 2009-06-16 13:55:57.=
000000000 -0500
+++ ./sys/rpc/rpcsec_gss/svc_rpcsec_gss.c 2009-06-16 13:56:18.000000000 -05=
00
@@ -449,11 +449,7 @@
cr =3D client->cl_cred =3D crget();
cr->cr_uid =3D cr->cr_ruid =3D cr->cr_svuid =3D uc->uid;
cr->cr_rgid =3D cr->cr_svgid =3D uc->gid;
- cr->cr_ngroups =3D uc->gidlen;
- if (cr->cr_ngroups > NGROUPS)
- cr->cr_ngroups =3D NGROUPS;
- for (i =3D 0; i < cr->cr_ngroups; i++)
- cr->cr_groups[i] =3D uc->gidlist[i];
+ crsetgroups(cr, uc->gidlen, uc->gidlist);
*crp =3D crhold(cr);
=20
return (TRUE);
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/rpc/svc_auth.c ./sys/rpc/svc_au=
th.c
--- /usr/fsvn/head/sys/rpc/svc_auth.c 2009-06-12 00:52:17.000000000 -0500
+++ ./sys/rpc/svc_auth.c 2009-06-12 01:13:12.000000000 -0500
@@ -166,7 +166,7 @@
svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
{
struct ucred *cr =3D NULL;
- int flavor, i;
+ int flavor;
struct xucred *xcr;
=20
flavor =3D rqst->rq_cred.oa_flavor;
@@ -178,9 +178,7 @@
xcr =3D (struct xucred *) rqst->rq_clntcred;
cr =3D crget();
cr->cr_uid =3D cr->cr_ruid =3D cr->cr_svuid =3D xcr->cr_uid;
- cr->cr_ngroups =3D xcr->cr_ngroups;
- for (i =3D 0; i < xcr->cr_ngroups; i++)
- cr->cr_groups[i] =3D xcr->cr_groups[i];
+ crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
cr->cr_rgid =3D cr->cr_svgid =3D cr->cr_groups[0];
cr->cr_prison =3D &prison0;
prison_hold(cr->cr_prison);
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/rpc/svc_auth_unix.c ./sys/rpc/s=
vc_auth_unix.c
--- /usr/fsvn/head/sys/rpc/svc_auth_unix.c 2009-01-22 10:05:57.000000000 -0=
600
+++ ./sys/rpc/svc_auth_unix.c 2009-06-09 08:49:37.000000000 -0500
@@ -95,13 +95,13 @@
goto done;
}
for (i =3D 0; i < gid_len; i++) {
- if (i + 1 < NGROUPS)
+ if (i + 1 < XU_NGROUPS)
xcr->cr_groups[i + 1] =3D IXDR_GET_INT32(buf);
else
buf++;
}
- if (gid_len + 1 > NGROUPS)
- xcr->cr_ngroups =3D NGROUPS;
+ if (gid_len + 1 > XU_NGROUPS)
+ xcr->cr_ngroups =3D XU_NGROUPS;
else
xcr->cr_ngroups =3D gid_len + 1;
=20
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/sys/param.h ./sys/sys/param.h
--- /usr/fsvn/head/sys/sys/param.h 2009-06-16 13:55:59.000000000 -0500
+++ ./sys/sys/param.h 2009-06-16 13:56:20.000000000 -0500
@@ -77,7 +77,7 @@
#define MAXLOGNAME 17 /* max login name length (incl. NUL) */
#define MAXUPRC CHILD_MAX /* max simultaneous processes */
#define NCARGS ARG_MAX /* max bytes for an exec function */
-#define NGROUPS NGROUPS_MAX /* max number groups */
+#define NGROUPS NGROUPS_MAX+1 /* max number groups */
#define NOFILE OPEN_MAX /* max open files per process */
#define NOGROUP 65535 /* marker for empty group set member */
#define MAXHOSTNAMELEN 256 /* max hostname size */
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/sys/syslimits.h ./sys/sys/sysli=
mits.h
--- /usr/fsvn/head/sys/sys/syslimits.h 2009-01-22 10:06:22.000000000 -0600
+++ ./sys/sys/syslimits.h 2009-06-08 23:57:36.000000000 -0500
@@ -54,7 +54,9 @@
#define MAX_CANON 255 /* max bytes in term canon input line */
#define MAX_INPUT 255 /* max bytes in terminal input */
#define NAME_MAX 255 /* max bytes in a file name */
-#define NGROUPS_MAX 16 /* max supplemental group id's */
+#ifndef NGROUPS_MAX
+#define NGROUPS_MAX 1023 /* max supplemental group id's */
+#endif
#ifndef OPEN_MAX
#define OPEN_MAX 64 /* max open files per process */
#endif
--- /usr/fsvn/head/sys/sys/ucred.h 2009-06-16 15:54:53.000000000 -0500
+++ ./sys/sys/ucred.h 2009-06-17 18:23:49.000000000 -0500
@@ -48,8 +48,7 @@
uid_t cr_uid; /* effective user id */
uid_t cr_ruid; /* real user id */
uid_t cr_svuid; /* saved user id */
- short cr_ngroups; /* number of groups */
- gid_t cr_groups[NGROUPS]; /* groups */
+ int cr_ngroups; /* number of groups */
gid_t cr_rgid; /* real group id */
gid_t cr_svgid; /* saved group id */
struct uidinfo *cr_uidinfo; /* per euid resource consumption */
@@ -61,11 +60,15 @@
#define cr_endcopy cr_label
struct label *cr_label; /* MAC label */
struct auditinfo_addr cr_audit; /* Audit properties. */
+ gid_t *cr_groups; /* groups */
+ int cr_agroups; /* Available groups */
};
#define NOCRED ((struct ucred *)0) /* no credential available */
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
#endif /* _KERNEL || _WANT_UCRED */
=20
+#define XU_NGROUPS 16
+
/*
* This is the external representation of struct ucred.
*/
@@ -73,7 +76,7 @@
u_int cr_version; /* structure layout version */
uid_t cr_uid; /* effective user id */
short cr_ngroups; /* number of groups */
- gid_t cr_groups[NGROUPS]; /* groups */
+ gid_t cr_groups[XU_NGROUPS]; /* groups */
void *_cr_unused1; /* compatibility with old ucred */
};
#define XUCRED_VERSION 0
@@ -82,6 +85,7 @@
#define cr_gid cr_groups[0]
=20
#ifdef _KERNEL
+struct proc;
struct thread;
=20
void change_egid(struct ucred *newcred, gid_t egid);
@@ -91,6 +95,7 @@
void change_svgid(struct ucred *newcred, gid_t svgid);
void change_svuid(struct ucred *newcred, uid_t svuid);
void crcopy(struct ucred *dest, struct ucred *src);
+struct ucred *crcopysafe(struct proc *p, struct ucred *cr);
struct ucred *crdup(struct ucred *cr);
void cred_update_thread(struct thread *td);
void crfree(struct ucred *cr);
@@ -98,6 +103,7 @@
struct ucred *crhold(struct ucred *cr);
int crshared(struct ucred *cr);
void cru2x(struct ucred *cr, struct xucred *xcr);
+void crsetgroups(struct ucred *cr, int n, gid_t *groups);
int groupmember(gid_t gid, struct ucred *cred);
#endif /* _KERNEL */
=20
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/sys/user.h ./sys/sys/user.h
--- /usr/fsvn/head/sys/sys/user.h 2009-06-16 15:54:53.000000000 -0500
+++ ./sys/sys/user.h 2009-06-05 16:02:34.000000000 -0500
@@ -85,7 +85,7 @@
*/
#define KI_NSPARE_INT 9
#define KI_NSPARE_LONG 12
-#define KI_NSPARE_PTR 7
+#define KI_NSPARE_PTR 6
=20
#ifdef __amd64__
#define KINFO_PROC_SIZE 1088
@@ -117,7 +117,6 @@
#define OCOMMLEN 16 /* size of returned thread name */
#define COMMLEN 19 /* size of returned ki_comm name */
#define KI_EMULNAMELEN 16 /* size of returned ki_emul */
-#define KI_NGROUPS 16 /* number of groups in ki_groups */
#define LOGNAMELEN 17 /* size of returned ki_login */
=20
struct kinfo_proc {
@@ -151,7 +150,7 @@
gid_t ki_svgid; /* Saved effective group id */
short ki_ngroups; /* number of groups */
short ki_spare_short2; /* unused (just here for alignment) */
- gid_t ki_groups[KI_NGROUPS]; /* groups */
+ uint32_t __was_ki_groups[16]; /* unused; left for bin compat */
vm_size_t ki_size; /* virtual size */
segsz_t ki_rssize; /* current resident set size in pages */
segsz_t ki_swrss; /* resident set size before last swap */
@@ -201,6 +200,7 @@
struct pcb *ki_pcb; /* kernel virtual addr of pcb */
void *ki_kstack; /* kernel virtual addr of stack */
void *ki_udata; /* User convenience pointer */
+ gid_t *ki_groups; /* groups */
/*
* When adding new variables, take space for pointers from the
* front of ki_spareptrs, and longs from the end of ki_sparelongs.
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/sys/ufs/ufs/ufs_vnops.c ./sys/ufs/u=
fs/ufs_vnops.c
--- /usr/fsvn/head/sys/ufs/ufs/ufs_vnops.c 2009-06-16 13:55:57.000000000 -0=
500
+++ ./sys/ufs/ufs/ufs_vnops.c 2009-06-16 13:56:20.000000000 -0500
@@ -2266,6 +2266,7 @@
{
#ifdef QUOTA
struct ucred ucred, *ucp;
+ gid_t ucred_group;
ucp =3D cnp->cn_cred;
#endif
/*
@@ -2292,6 +2293,7 @@
refcount_init(&ucred.cr_ref, 1);
ucred.cr_uid =3D ip->i_uid;
ucred.cr_ngroups =3D 1;
+ ucred.cr_groups =3D &ucred_group;
ucred.cr_groups[0] =3D pdir->i_gid;
ucp =3D &ucred;
#endif
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/mount_portalfs/portald.h .=
/usr.sbin/mount_portalfs/portald.h
--- /usr/fsvn/head/usr.sbin/mount_portalfs/portald.h 2009-01-22 10:05:31.00=
0000000 -0600
+++ ./usr.sbin/mount_portalfs/portald.h 2009-06-17 13:41:26.000000000 -0500
@@ -36,6 +36,7 @@
*/
=20
#include <sys/cdefs.h>
+#include <sys/ucred.h>
#include <fs/portalfs/portal.h>
=20
/*
diff -ru --exclude=3D.svn --exclude=3Dcompile --exclude=3Dcardbus.c --ignor=
e-matching=3D'$FreeBSD:' /usr/fsvn/head/usr.sbin/mountd/mountd.c ./usr.sbin=
/mountd/mountd.c
--- /usr/fsvn/head/usr.sbin/mountd/mountd.c 2009-06-16 15:54:05.000000000 -=
0500
+++ ./usr.sbin/mountd/mountd.c 2009-06-17 15:25:33.000000000 -0500
@@ -2644,7 +2644,7 @@
char *names;
struct passwd *pw;
struct group *gr;
- gid_t groups[NGROUPS + 1];
+ gid_t groups[XU_NGROUPS + 1];
int ngroups;
=20
cr->cr_version =3D XUCRED_VERSION;
@@ -2672,7 +2672,7 @@
return;
}
cr->cr_uid =3D pw->pw_uid;
- ngroups =3D NGROUPS + 1;
+ ngroups =3D XU_NGROUPS + 1;
if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups))
syslog(LOG_ERR, "too many groups");
/*
@@ -2697,7 +2697,7 @@
return;
}
cr->cr_ngroups =3D 0;
- while (names !=3D NULL && *names !=3D '\0' && cr->cr_ngroups < NGROUPS) {
+ while (names !=3D NULL && *names !=3D '\0' && cr->cr_ngroups < XU_NGROUPS=
) {
name =3D strsep(&names, ":");
if (isdigit(*name) || *name =3D=3D '-') {
cr->cr_groups[cr->cr_ngroups++] =3D atoi(name);
@@ -2709,7 +2709,7 @@
cr->cr_groups[cr->cr_ngroups++] =3D gr->gr_gid;
}
}
- if (names !=3D NULL && *names !=3D '\0' && cr->cr_ngroups =3D=3D NGROUPS)
+ if (names !=3D NULL && *names !=3D '\0' && cr->cr_ngroups =3D=3D XU_NGROU=
PS)
syslog(LOG_ERR, "too many groups");
}
=20
--YZ5djTAD1cGYuMQK--
--O5XBE6gyVG5Rl6Rj
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (FreeBSD)
iD8DBQFKOYTKXY6L6fI4GtQRAoiYAJ9BzCBNbP/75Un8IE0lnANi+vLzcACgvb3y
Qn1aK6Ca1A8ZeOXWFkULVJo=
=wA9V
-----END PGP SIGNATURE-----
--O5XBE6gyVG5Rl6Rj--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090618000531.GA46033>
