Catch up to dynamically-sized cr_groups in FBSD80
authorBen Kaduk <kaduk@mit.edu>
Tue, 23 Mar 2010 02:35:51 +0000 (22:35 -0400)
committerDerrick Brashear <shadow@dementia.org>
Mon, 29 Mar 2010 04:34:31 +0000 (21:34 -0700)
In FreeBSD 8.0 and later, (struct ucred)->cr_groups is a pointer
to a dynamically-allocated array, and NGROUPS is now 1024 by default
(tuneable at boot).
Don't put a gid_t[NGROUPS] on the stack for the FBSD80_ENV case.
Also avoid keeping a function-local ucred structure (in
afs_osi_proc2cred()), by bypassing that function entirely
(though this accesses the process credentials directly, which may
require locking; thread credentials accesses can be safely done
lock-free).  Add an osi_Panic() to ensure that it stays that way.
Don't pretend that we have a useful afs_osi_cred to export.
Don't blindly overwrite NGROUPS past cr_groups.

Change-Id: I76295164a24bddf2782ab2fa662acd0e1b4855d6
Reviewed-on: http://gerrit.openafs.org/1665
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/FBSD/osi_file.c
src/afs/FBSD/osi_groups.c
src/afs/afs_osi_gcpags.c
src/afs/afs_pioctl.c
src/afs/afs_user.c

index 94e8591..738fd27 100644 (file)
@@ -17,7 +17,9 @@
 
 
 int afs_osicred_initialized = 0;
+#ifndef AFS_FBSD80_ENV /* cr_groups is now malloc()'d */
 afs_ucred_t afs_osi_cred;
+#endif
 afs_lock_t afs_xosi;           /* lock is for tvattr */
 extern struct osi_dev cacheDev;
 extern struct mount *afs_cacheVfsp;
index 2ed4069..9e6d47f 100644 (file)
@@ -125,15 +125,24 @@ int
 setpag(struct proc *proc, struct ucred **cred, afs_uint32 pagvalue,
        afs_uint32 * newpag, int change_parent)
 {
+#ifdef AFS_FBSD80_ENV
+    gid_t *gidset;
+    int gidset_len = ngroups_max;
+#else
     gid_t gidset[NGROUPS];
+    int gidset_len = NGROUPS;
+#endif
     int ngroups, code;
     int j;
 
     AFS_STATCNT(setpag);
-    ngroups = afs_getgroups(*cred, NGROUPS, gidset);
+#ifdef AFS_FBSD80_ENV
+    gidset = osi_Alloc(gidset_len * sizeof(gid_t));
+#endif
+    ngroups = afs_getgroups(*cred, gidset_len, gidset);
     if (afs_get_pag_from_groups(gidset[1], gidset[2]) == NOPAG) {
        /* We will have to shift grouplist to make room for pag */
-       if (ngroups + 2 > NGROUPS) {
+       if (ngroups + 2 > gidset_len) {
            return (E2BIG);
        }
        for (j = ngroups - 1; j >= 1; j--) {
@@ -144,6 +153,9 @@ setpag(struct proc *proc, struct ucred **cred, afs_uint32 pagvalue,
     *newpag = (pagvalue == -1 ? genpag() : pagvalue);
     afs_get_groups_from_pag(*newpag, &gidset[1], &gidset[2]);
     code = afs_setgroups(proc, cred, ngroups, gidset, change_parent);
+#ifdef AFS_FBSD80_ENV
+    osi_Free(gidset, gidset_len * sizeof(gid_t));
+#endif
     return code;
 }
 
index 0c34297..06c7946 100644 (file)
@@ -436,6 +436,9 @@ afs_osi_proc2cred(afs_proc_t * pr)
 {
     afs_ucred_t *rv = NULL;
     static afs_ucred_t cr;
+#if defined(AFS_FBSD80_ENV)
+    osi_Panic("proc2cred broken for dynamic cr_groups");
+#endif
 
     if (pr == NULL) {
        return NULL;
index 345f2ef..9f6e4b4 100644 (file)
@@ -4490,7 +4490,7 @@ HandleClientContext(struct afs_ioctl *ablob, int *com,
 #ifdef AFS_AIX_ENV
     newcred->cr_ngrps = 2;
 #elif !defined(AFS_LINUX26_ENV) && !defined(AFS_SUN510_ENV)
-# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV)
+# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_FBSD80_ENV)
     newcred->cr_ngroups = 2;
 # else
     for (i = 2; i < NGROUPS; i++)
index 3e9fd95..30e452e 100644 (file)
@@ -631,7 +631,11 @@ afs_GCPAGs_perproc_func(afs_proc_t * pproc)
 
     afs_GCPAGs_perproc_count++;
 
+#if defined(AFS_FBSD80_ENV)
+    pcred = pproc->p_ucred;    /* XXX locking (or just use thread creds) */
+#else
     pcred = afs_osi_proc2cred(pproc);
+#endif
     if (!pcred)
        return;