solaris-p-crlock-not-safe-to-hold-across-call-to-crset-20020206
authorNickolai Zeldovich <kolya@mit.edu>
Wed, 6 Feb 2002 23:57:44 +0000 (23:57 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 6 Feb 2002 23:57:44 +0000 (23:57 +0000)
crset() expects p_crlock to not be held when it's called; deal accordingly

src/afs/SOLARIS/osi_groups.c
src/afs/afs_call.c

index 37be483..86b2518 100644 (file)
@@ -91,6 +91,8 @@ setpag(cred, pagvalue, newpag, change_parent)
     AFS_STATCNT(setpag);
 
     gidset = (gid_t *) osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+
+    mutex_enter(&curproc->p_crlock);
     ngroups = afs_getgroups(*cred, gidset);
 
     if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) {
@@ -106,6 +108,7 @@ setpag(cred, pagvalue, newpag, change_parent)
     }
     *newpag = (pagvalue == -1 ? genpag(): pagvalue);
     afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]);
+    /* afs_setgroups will release curproc->p_crlock */
     if (code = afs_setgroups(cred, ngroups, gidset, change_parent)) {
        osi_FreeSmallSpace((char *)gidset);
        return (code);
@@ -148,17 +151,18 @@ afs_setgroups(
 
     AFS_STATCNT(afs_setgroups);
 
-    if (ngroups > ngroups_max)
+    if (ngroups > ngroups_max) {
+       mutex_exit(&curproc->p_crlock);
        return EINVAL;
+    }
     if (!change_parent)
        *cred = (struct cred *)crcopy(*cred);
     (*cred)->cr_ngroups = ngroups;
     gp = (*cred)->cr_groups;
     while (ngroups--)
        *gp++ = *gidset++;
-    if (!change_parent) {
-       struct proc *proc = ttoproc(curthread);
-       crset(proc, *cred); /* broadcast to all threads */
-    }
+    mutex_exit(&curproc->p_crlock);
+    if (!change_parent)
+       crset(curproc, *cred); /* broadcast to all threads */
     return (0);
 }
index 7e53877..65d0e02 100644 (file)
@@ -1072,17 +1072,12 @@ Afs_syscall ()
 #endif
     } else if (uap->syscall == AFSCALL_SETPAG) {
 #ifdef AFS_SUN5_ENV
-       struct cred *cred;
        register proc_t *procp;
 
        procp = ttoproc(curthread);
-       mutex_enter(&procp->p_crlock);
-       cred = procp->p_cred; 
        AFS_GLOCK();
-       code =  afs_setpag(&cred);
+       code =  afs_setpag(&procp->p_cred);
        AFS_GUNLOCK();
-       procp->p_cred = cred;
-       mutex_exit(&procp->p_crlock);
 #else
        AFS_GLOCK();
 #if    defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)