Author: kan
Date: Sat May  9 18:09:17 2009
New Revision: 191940
URL: http://svn.freebsd.org/changeset/base/191940

Log:
  Do not embed struct ucred into larger netcred parent structures.
  
  Credential might need to hang around longer than its parent and be used
  outside of mnt_explock scope controlling netcred lifetime. Use separate
  reference-counted ucred allocated separately instead.
  
  While there, extend mnt_explock coverage in vfs_stdexpcheck and clean-up
  some unused declarations in new NFS code.
  
  Reported by:  John Hickey
  PR:           kern/133439
  Reviewed by:  dfr, kib

Modified:
  head/sys/fs/nfs/nfsport.h
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/fs/nfsserver/nfs_nfsdsocket.c
  head/sys/kern/vfs_export.c
  head/sys/nfsserver/nfs_srvsubs.c
  head/sys/nlm/nlm_prot_impl.c
  head/sys/ufs/ufs/ufs_extern.h

Modified: head/sys/fs/nfs/nfsport.h
==============================================================================
--- head/sys/fs/nfs/nfsport.h   Sat May  9 17:47:42 2009        (r191939)
+++ head/sys/fs/nfs/nfsport.h   Sat May  9 18:09:17 2009        (r191940)
@@ -446,16 +446,6 @@ int nfsmsleep(void *, void *, int, const
 #define        VT_NFSV4ROOT            "nfsv4root"
 
 /*
- * XXX - not in any system .h file, just vfs_export.c
- * Network address lookup element
- */
-struct netcred {
-       struct  radix_node netc_rnodes[2];
-       int     netc_exflags;
-       struct  ucred netc_anon;
-};
-
-/*
  * Define whatever it takes to do a vn_rdwr().
  */
 #define        NFSD_RDWR(r, v, b, l, o, s, i, c, a, p) \

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c        Sat May  9 17:47:42 2009        
(r191939)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c        Sat May  9 18:09:17 2009        
(r191940)
@@ -2565,6 +2565,8 @@ nfsd_fhtovp(struct nfsrv_descript *nd, s
                if (nd->nd_repstat)
                        vput(*vpp);
        }
+       if (credanon != NULL)
+               crfree(credanon);
        if (nd->nd_repstat) {
                if (startwrite)
                        vn_finished_write(mp);
@@ -2598,16 +2600,6 @@ fp_getfvp(struct thread *p, int fd, stru
 }
 
 /*
- * Network export information
- */
-struct netexport {
-       struct  netcred ne_defexported;               /* Default export */
-       struct  radix_node_head *ne_rtable[AF_MAX+1]; /* Individual exports */
-};
-
-struct netexport nfsv4root_export;
-
-/*
  * Called from newnfssvc() to update the exports list. Just call
  * vfs_export(). This has to be done, since the v4 root fake fs isn't
  * in the mount list.
@@ -2861,6 +2853,8 @@ nfsvno_v4rootexport(struct nfsrv_descrip
                return (NFSERR_PROGUNAVAIL);
        if ((exflags & MNT_EXGSSONLY))
                nd->nd_flag |= ND_EXGSSONLY;
+       if (credanon != NULL)
+               crfree(credanon);
        return (0);
 }
 

Modified: head/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdsocket.c      Sat May  9 17:47:42 2009        
(r191939)
+++ head/sys/fs/nfsserver/nfs_nfsdsocket.c      Sat May  9 18:09:17 2009        
(r191940)
@@ -870,6 +870,8 @@ nfsrvd_compound(struct nfsrv_descript *n
                                    if (!nd->nd_repstat)
                                        nd->nd_repstat = nfsd_excred(nd,
                                            &nes, credanon);
+                                   if (credanon != NULL)
+                                       crfree(credanon);
                                    if (!nd->nd_repstat) {
                                        if (vpnes.nes_vfslocked)
                                            nfsvno_unlockvfs(mp);

Modified: head/sys/kern/vfs_export.c
==============================================================================
--- head/sys/kern/vfs_export.c  Sat May  9 17:47:42 2009        (r191939)
+++ head/sys/kern/vfs_export.c  Sat May  9 18:09:17 2009        (r191940)
@@ -68,7 +68,7 @@ static struct netcred *vfs_export_lookup
 struct netcred {
        struct  radix_node netc_rnodes[2];
        int     netc_exflags;
-       struct  ucred netc_anon;
+       struct  ucred *netc_anon;
        int     netc_numsecflavors;
        int     netc_secflavors[MAXSECFLAVORS];
 };
@@ -83,7 +83,7 @@ struct netexport {
 
 /*
  * Build hash lists of net addresses and hang them off the mount point.
- * Called by ufs_mount() to set up the lists of export addresses.
+ * Called by vfs_export() to set up the lists of export addresses.
  */
 static int
 vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
@@ -118,15 +118,14 @@ vfs_hang_addrlist(struct mount *mp, stru
                }
                np = &nep->ne_defexported;
                np->netc_exflags = argp->ex_flags;
-               bzero(&np->netc_anon, sizeof(np->netc_anon));
-               np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
-               np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
-               bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
-                   sizeof(np->netc_anon.cr_groups));
+               np->netc_anon = crget();
+               np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
+               np->netc_anon->cr_ngroups = argp->ex_anon.cr_ngroups;
+               bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups,
+                   sizeof(np->netc_anon->cr_groups));
                np->netc_numsecflavors = argp->ex_numsecflavors;
                bcopy(argp->ex_secflavors, np->netc_secflavors,
                    sizeof(np->netc_secflavors));
-               refcount_init(&np->netc_anon.cr_ref, 1);
                MNT_ILOCK(mp);
                mp->mnt_flag |= MNT_DEFEXPORTED;
                MNT_IUNLOCK(mp);
@@ -204,15 +203,14 @@ vfs_hang_addrlist(struct mount *mp, stru
                goto out;
        }
        np->netc_exflags = argp->ex_flags;
-       bzero(&np->netc_anon, sizeof(np->netc_anon));
-       np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
-       np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
-       bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
-           sizeof(np->netc_anon.cr_groups));
+       np->netc_anon = crget();
+       np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
+       np->netc_anon->cr_ngroups = argp->ex_anon.cr_ngroups;
+       bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups,
+           sizeof(np->netc_anon->cr_groups));
        np->netc_numsecflavors = argp->ex_numsecflavors;
        bcopy(argp->ex_secflavors, np->netc_secflavors,
            sizeof(np->netc_secflavors));
-       refcount_init(&np->netc_anon.cr_ref, 1);
        return (0);
 out:
        free(np, M_NETADDR);
@@ -267,9 +265,9 @@ vfs_export(struct mount *mp, struct expo
            || argp->ex_numsecflavors >= MAXSECFLAVORS)
                return (EINVAL);
 
-       nep = mp->mnt_export;
        error = 0;
        lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL);
+       nep = mp->mnt_export;
        if (argp->ex_flags & MNT_DELEXPORT) {
                if (nep == NULL) {
                        error = ENOENT;
@@ -375,8 +373,9 @@ vfs_setpublicfs(struct mount *mp, struct
         * If an indexfile was specified, pull it in.
         */
        if (argp->ex_indexfile != NULL) {
-               nfs_pub.np_index = malloc(MAXNAMLEN + 1, M_TEMP,
-                   M_WAITOK);
+               if (nfs_pub.np_index != NULL)
+                       nfs_pub.np_index = malloc(MAXNAMLEN + 1, M_TEMP,
+                           M_WAITOK);
                error = copyinstr(argp->ex_indexfile, nfs_pub.np_index,
                    MAXNAMLEN, (size_t *)0);
                if (!error) {
@@ -392,6 +391,7 @@ vfs_setpublicfs(struct mount *mp, struct
                }
                if (error) {
                        free(nfs_pub.np_index, M_TEMP);
+                       nfs_pub.np_index = NULL;
                        return (error);
                }
        }
@@ -461,15 +461,19 @@ vfs_stdcheckexp(struct mount *mp, struct
 
        lockmgr(&mp->mnt_explock, LK_SHARED, NULL);
        np = vfs_export_lookup(mp, nam);
-       lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
-       if (np == NULL)
+       if (np == NULL) {
+               lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
+               *credanonp = NULL;
                return (EACCES);
+       }
        *extflagsp = np->netc_exflags;
-       *credanonp = &np->netc_anon;
+       if ((*credanonp = np->netc_anon) != NULL)
+               crhold(*credanonp);
        if (numsecflavors)
                *numsecflavors = np->netc_numsecflavors;
        if (secflavors)
                *secflavors = np->netc_secflavors;
+       lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
        return (0);
 }
 

Modified: head/sys/nfsserver/nfs_srvsubs.c
==============================================================================
--- head/sys/nfsserver/nfs_srvsubs.c    Sat May  9 17:47:42 2009        
(r191939)
+++ head/sys/nfsserver/nfs_srvsubs.c    Sat May  9 18:09:17 2009        
(r191940)
@@ -1193,6 +1193,9 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockfla
        if (!lockflag)
                VOP_UNLOCK(*vpp, 0);
 out:
+       if (credanon != NULL)
+               crfree(credanon);
+
        if (error) {
                VFS_UNLOCK_GIANT(vfslocked);
        } else

Modified: head/sys/nlm/nlm_prot_impl.c
==============================================================================
--- head/sys/nlm/nlm_prot_impl.c        Sat May  9 17:47:42 2009        
(r191939)
+++ head/sys/nlm/nlm_prot_impl.c        Sat May  9 18:09:17 2009        
(r191940)
@@ -1752,7 +1752,8 @@ nlm_get_vfs_state(struct nlm_host *host,
        }
        if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) {
                crfree(cred);
-               cred = crhold(credanon);
+               cred = credanon;
+               credanon = NULL;
        }
 
        /*
@@ -1772,6 +1773,8 @@ nlm_get_vfs_state(struct nlm_host *host,
 out:
        if (cred)
                crfree(cred);
+       if (credanon)
+               crfree(credanon);
 
        return (error);
 }

Modified: head/sys/ufs/ufs/ufs_extern.h
==============================================================================
--- head/sys/ufs/ufs/ufs_extern.h       Sat May  9 17:47:42 2009        
(r191939)
+++ head/sys/ufs/ufs/ufs_extern.h       Sat May  9 18:09:17 2009        
(r191940)
@@ -38,7 +38,6 @@ struct direct;
 struct indir;
 struct inode;
 struct mount;
-struct netcred;
 struct thread;
 struct sockaddr;
 struct ucred;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to