svn commit: r362158 - in head/sys: cddl/contrib/opensolaris/uts/common/fs/zfs fs/cd9660 fs/msdosfs fs/nfs fs/nfsserver fs/unionfs kern nlm sys ufs/ffs

Rick Macklem rmacklem at FreeBSD.org
Sun Jun 14 00:10:21 UTC 2020


Author: rmacklem
Date: Sun Jun 14 00:10:18 2020
New Revision: 362158
URL: https://svnweb.freebsd.org/changeset/base/362158

Log:
  Fix export_args ex_flags field so that is 64bits, the same as mnt_flags.
  
  Since mnt_flags was upgraded to 64bits there has been a quirk in
  "struct export_args", since it hold a copy of mnt_flags
  in ex_flags, which is an "int" (32bits).
  This happens to currently work, since all the flag bits used in ex_flags are
  defined in the low order 32bits. However, new export flags cannot be defined.
  Also, ex_anon is a "struct xucred", which limits it to 16 additional groups.
  This patch revises "struct export_args" to make ex_flags 64bits and replaces
  ex_anon with ex_uid, ex_ngroups and ex_groups (which points to a
  groups list, so it can be malloc'd up to NGROUPS in size.
  This requires that the VFS_CHECKEXP() arguments change, so I also modified the
  last "secflavors" argument to be an array pointer, so that the
  secflavors could be copied in VFS_CHECKEXP() while the export entry is locked.
  (Without this patch VFS_CHECKEXP() returns a pointer to the secflavors
  array and then it is used after being unlocked, which is potentially
  a problem if the exports entry is changed.
  In practice this does not occur when mountd is run with "-S",
  but I think it is worth fixing.)
  
  This patch also deleted the vfs_oexport_conv() function, since
  do_mount_update() does the conversion, as required by the old vfs_cmount()
  calls.
  
  Reviewed by:	kib, freqlabs
  Relnotes:	yes
  Differential Revision:	https://reviews.freebsd.org/D25088

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  head/sys/fs/cd9660/cd9660_vfsops.c
  head/sys/fs/msdosfs/msdosfs_vfsops.c
  head/sys/fs/nfs/nfsdport.h
  head/sys/fs/nfs/nfsport.h
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/fs/unionfs/union_vfsops.c
  head/sys/kern/vfs_export.c
  head/sys/kern/vfs_init.c
  head/sys/kern/vfs_mount.c
  head/sys/nlm/nlm_prot_impl.c
  head/sys/sys/mount.h
  head/sys/ufs/ffs/ffs_vfsops.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -101,8 +101,8 @@ static int zfs_root(vfs_t *vfsp, int flags, vnode_t **
 static int zfs_statfs(vfs_t *vfsp, struct statfs *statp);
 static int zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp);
 static int zfs_sync(vfs_t *vfsp, int waitfor);
-static int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
-    struct ucred **credanonp, int *numsecflavors, int **secflavors);
+static int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, uint64_t *extflagsp,
+    struct ucred **credanonp, int *numsecflavors, int *secflavors);
 static int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp);
 static void zfs_objset_close(zfsvfs_t *zfsvfs);
 static void zfs_freevfs(vfs_t *vfsp);
@@ -2268,8 +2268,8 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **
 }
 
 static int
-zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp,
-    struct ucred **credanonp, int *numsecflavors, int **secflavors)
+zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, uint64_t *extflagsp,
+    struct ucred **credanonp, int *numsecflavors, int *secflavors)
 {
 	zfsvfs_t *zfsvfs = vfsp->vfs_data;
 

Modified: head/sys/fs/cd9660/cd9660_vfsops.c
==============================================================================
--- head/sys/fs/cd9660/cd9660_vfsops.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/fs/cd9660/cd9660_vfsops.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -101,16 +101,14 @@ static int
 cd9660_cmount(struct mntarg *ma, void *data, uint64_t flags)
 {
 	struct iso_args args;
-	struct export_args exp;
 	int error;
 
 	error = copyin(data, &args, sizeof args);
 	if (error)
 		return (error);
-	vfs_oexport_conv(&args.export, &exp);
 
 	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
-	ma = mount_arg(ma, "export", &exp, sizeof(exp));
+	ma = mount_arg(ma, "export", &args.export, sizeof(args.export));
 	ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64);
 	ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
 	ma = mount_argf(ma, "ssector", "%u", args.ssector);

Modified: head/sys/fs/msdosfs/msdosfs_vfsops.c
==============================================================================
--- head/sys/fs/msdosfs/msdosfs_vfsops.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/fs/msdosfs/msdosfs_vfsops.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -190,7 +190,6 @@ static int
 msdosfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
 {
 	struct msdosfs_args args;
-	struct export_args exp;
 	int error;
 
 	if (data == NULL)
@@ -198,10 +197,9 @@ msdosfs_cmount(struct mntarg *ma, void *data, uint64_t
 	error = copyin(data, &args, sizeof args);
 	if (error)
 		return (error);
-	vfs_oexport_conv(&args.export, &exp);
 
 	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
-	ma = mount_arg(ma, "export", &exp, sizeof(exp));
+	ma = mount_arg(ma, "export", &args.export, sizeof(args.export));
 	ma = mount_argf(ma, "uid", "%d", args.uid);
 	ma = mount_argf(ma, "gid", "%d", args.gid);
 	ma = mount_argf(ma, "mask", "%d", args.mask);

Modified: head/sys/fs/nfs/nfsdport.h
==============================================================================
--- head/sys/fs/nfs/nfsdport.h	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/fs/nfs/nfsdport.h	Sun Jun 14 00:10:18 2020	(r362158)
@@ -54,7 +54,7 @@
  * needs to be returned by nfsd_fhtovp().
  */
 struct nfsexstuff {
-	int	nes_exflag;			/* export flags */
+	uint64_t nes_exflag;			/* export flags */
 	int	nes_numsecflavor;		/* # of security flavors */
 	int	nes_secflavors[MAXSECFLAVORS];	/* and the flavors */
 };

Modified: head/sys/fs/nfs/nfsport.h
==============================================================================
--- head/sys/fs/nfs/nfsport.h	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/fs/nfs/nfsport.h	Sun Jun 14 00:10:18 2020	(r362158)
@@ -1081,6 +1081,11 @@ struct nfsex_args {
 	struct export_args	export;
 };
 
+struct nfsex_oldargs {
+	char	*fspec;
+	struct o2export_args	export;
+};
+
 /*
  * These export flags should be defined, but there are no bits left.
  * Maybe a separate mnt_exflag field could be added or the mnt_flag

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -3056,10 +3056,10 @@ int
 nfsvno_checkexp(struct mount *mp, struct sockaddr *nam, struct nfsexstuff *exp,
     struct ucred **credp)
 {
-	int i, error, *secflavors;
+	int error;
 
 	error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
-	    &exp->nes_numsecflavor, &secflavors);
+	    &exp->nes_numsecflavor, exp->nes_secflavors);
 	if (error) {
 		if (nfs_rootfhset) {
 			exp->nes_exflag = 0;
@@ -3071,10 +3071,6 @@ nfsvno_checkexp(struct mount *mp, struct sockaddr *nam
 		printf("nfsvno_checkexp: numsecflavors out of range\n");
 		exp->nes_numsecflavor = 0;
 		error = EACCES;
-	} else {
-		/* Copy the security flavors. */
-		for (i = 0; i < exp->nes_numsecflavor; i++)
-			exp->nes_secflavors[i] = secflavors[i];
 	}
 	NFSEXITCODE(error);
 	return (error);
@@ -3088,7 +3084,7 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct
     int lktype, struct vnode **vpp, struct nfsexstuff *exp,
     struct ucred **credp)
 {
-	int i, error, *secflavors;
+	int error;
 
 	*credp = NULL;
 	exp->nes_numsecflavor = 0;
@@ -3098,7 +3094,7 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct
 		error = ESTALE;
 	if (nam && !error) {
 		error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
-		    &exp->nes_numsecflavor, &secflavors);
+		    &exp->nes_numsecflavor, exp->nes_secflavors);
 		if (error) {
 			if (nfs_rootfhset) {
 				exp->nes_exflag = 0;
@@ -3113,10 +3109,6 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct
 			exp->nes_numsecflavor = 0;
 			error = EACCES;
 			vput(*vpp);
-		} else {
-			/* Copy the security flavors. */
-			for (i = 0; i < exp->nes_numsecflavor; i++)
-				exp->nes_secflavors[i] = secflavors[i];
 		}
 	}
 	NFSEXITCODE(error);
@@ -3415,10 +3407,11 @@ int
 nfsvno_v4rootexport(struct nfsrv_descript *nd)
 {
 	struct ucred *credanon;
-	int exflags, error = 0, numsecflavor, *secflavors, i;
+	int error = 0, numsecflavor, secflavors[MAXSECFLAVORS], i;
+	uint64_t exflags;
 
 	error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags,
-	    &credanon, &numsecflavor, &secflavors);
+	    &credanon, &numsecflavor, secflavors);
 	if (error) {
 		error = NFSERR_PROGUNAVAIL;
 		goto out;
@@ -3656,8 +3649,9 @@ static int
 nfssvc_srvcall(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
 {
 	struct nfsex_args export;
+	struct nfsex_oldargs oexp;
 	struct file *fp = NULL;
-	int stablefd, len;
+	int stablefd, i, len;
 	struct nfsd_clid adminrevoke;
 	struct nfsd_dumplist dumplist;
 	struct nfsd_dumpclients *dumpclients;
@@ -3667,6 +3661,7 @@ nfssvc_srvcall(struct thread *p, struct nfssvc_args *u
 	vnode_t vp;
 	int error = EINVAL, igotlock;
 	struct proc *procp;
+	gid_t *grps;
 	static int suspend_nfsd = 0;
 
 	if (uap->flag & NFSSVC_PUBLICFH) {
@@ -3676,11 +3671,71 @@ nfssvc_srvcall(struct thread *p, struct nfssvc_args *u
 		    &nfs_pubfh.nfsrvfh_data, sizeof (fhandle_t));
 		if (!error)
 			nfs_pubfhset = 1;
-	} else if (uap->flag & NFSSVC_V4ROOTEXPORT) {
+	} else if ((uap->flag & (NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT)) ==
+	    (NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT)) {
 		error = copyin(uap->argp,(caddr_t)&export,
 		    sizeof (struct nfsex_args));
-		if (!error)
-			error = nfsrv_v4rootexport(&export, cred, p);
+		if (!error) {
+			grps = NULL;
+			if (export.export.ex_ngroups > NGROUPS_MAX ||
+			    export.export.ex_ngroups < 0)
+				error = EINVAL;
+			else if (export.export.ex_ngroups > 0) {
+				grps = malloc(export.export.ex_ngroups *
+				    sizeof(gid_t), M_TEMP, M_WAITOK);
+				error = copyin(export.export.ex_groups, grps,
+				    export.export.ex_ngroups * sizeof(gid_t));
+				export.export.ex_groups = grps;
+			} else
+				export.export.ex_groups = NULL;
+			if (!error)
+				error = nfsrv_v4rootexport(&export, cred, p);
+			free(grps, M_TEMP);
+		}
+	} else if ((uap->flag & (NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT)) ==
+	    NFSSVC_V4ROOTEXPORT) {
+		error = copyin(uap->argp,(caddr_t)&oexp,
+		    sizeof (struct nfsex_oldargs));
+		if (!error) {
+			memset(&export.export, 0, sizeof(export.export));
+			export.export.ex_flags = (uint64_t)oexp.export.ex_flags;
+			export.export.ex_root = oexp.export.ex_root;
+			export.export.ex_uid = oexp.export.ex_anon.cr_uid;
+			export.export.ex_ngroups =
+			    oexp.export.ex_anon.cr_ngroups;
+			export.export.ex_groups = NULL;
+			if (export.export.ex_ngroups > XU_NGROUPS ||
+			    export.export.ex_ngroups < 0)
+				error = EINVAL;
+			else if (export.export.ex_ngroups > 0) {
+				export.export.ex_groups = malloc(
+				    export.export.ex_ngroups * sizeof(gid_t),
+				    M_TEMP, M_WAITOK);
+				for (i = 0; i < export.export.ex_ngroups; i++)
+					export.export.ex_groups[i] =
+					    oexp.export.ex_anon.cr_groups[i];
+			}
+			export.export.ex_addr = oexp.export.ex_addr;
+			export.export.ex_addrlen = oexp.export.ex_addrlen;
+			export.export.ex_mask = oexp.export.ex_mask;
+			export.export.ex_masklen = oexp.export.ex_masklen;
+			export.export.ex_indexfile = oexp.export.ex_indexfile;
+			export.export.ex_numsecflavors =
+			    oexp.export.ex_numsecflavors;
+			if (export.export.ex_numsecflavors >= MAXSECFLAVORS ||
+			    export.export.ex_numsecflavors < 0)
+				error = EINVAL;
+			else {
+				for (i = 0; i < export.export.ex_numsecflavors;
+				    i++)
+					export.export.ex_secflavors[i] =
+					    oexp.export.ex_secflavors[i];
+			}
+			export.fspec = oexp.fspec;
+			if (error == 0)
+				error = nfsrv_v4rootexport(&export, cred, p);
+			free(export.export.ex_groups, M_TEMP);
+		}
 	} else if (uap->flag & NFSSVC_NOPUBLICFH) {
 		nfs_pubfhset = 0;
 		error = 0;

Modified: head/sys/fs/unionfs/union_vfsops.c
==============================================================================
--- head/sys/fs/unionfs/union_vfsops.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/fs/unionfs/union_vfsops.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -461,8 +461,8 @@ unionfs_fhtovp(struct mount *mp, struct fid *fidp, int
 }
 
 static int
-unionfs_checkexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
-    struct ucred **credanonp, int *numsecflavors, int **secflavors)
+unionfs_checkexp(struct mount *mp, struct sockaddr *nam, uint64_t *extflagsp,
+    struct ucred **credanonp, int *numsecflavors, int *secflavors)
 {
 	return (EOPNOTSUPP);
 }

Modified: head/sys/kern/vfs_export.c
==============================================================================
--- head/sys/kern/vfs_export.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/kern/vfs_export.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -79,7 +79,7 @@ static struct netcred *vfs_export_lookup(struct mount 
  */
 struct netcred {
 	struct	radix_node netc_rnodes[2];
-	int	netc_exflags;
+	uint64_t netc_exflags;
 	struct	ucred *netc_anon;
 	int	netc_numsecflavors;
 	int	netc_secflavors[MAXSECFLAVORS];
@@ -118,18 +118,12 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *
 	    ("%s: numsecflavors >= MAXSECFLAVORS", __func__));
 
 	/*
-	 * XXX: This routine converts from a `struct xucred'
-	 * (argp->ex_anon) to a `struct ucred' (np->netc_anon).  This
+	 * XXX: This routine converts from a uid plus gid list
+	 * to a `struct ucred' (np->netc_anon).  This
 	 * operation is questionable; for example, what should be done
 	 * with fields like cr_uidinfo and cr_prison?  Currently, this
 	 * routine does not touch them (leaves them as NULL).
 	 */
-	if (argp->ex_anon.cr_version != XUCRED_VERSION) {
-		vfs_mount_error(mp, "ex_anon.cr_version: %d != %d",
-		    argp->ex_anon.cr_version, XUCRED_VERSION);
-		return (EINVAL);
-	}
-
 	if (argp->ex_addrlen == 0) {
 		if (mp->mnt_flag & MNT_DEFEXPORTED) {
 			vfs_mount_error(mp,
@@ -139,9 +133,9 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *
 		np = &nep->ne_defexported;
 		np->netc_exflags = argp->ex_flags;
 		np->netc_anon = crget();
-		np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
-		crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
-		    argp->ex_anon.cr_groups);
+		np->netc_anon->cr_uid = argp->ex_uid;
+		crsetgroups(np->netc_anon, argp->ex_ngroups,
+		    argp->ex_groups);
 		np->netc_anon->cr_prison = &prison0;
 		prison_hold(np->netc_anon->cr_prison);
 		np->netc_numsecflavors = argp->ex_numsecflavors;
@@ -218,9 +212,9 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *
 	}
 	np->netc_exflags = argp->ex_flags;
 	np->netc_anon = crget();
-	np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
-	crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
-	    argp->ex_anon.cr_groups);
+	np->netc_anon->cr_uid = argp->ex_uid;
+	crsetgroups(np->netc_anon, argp->ex_ngroups,
+	    argp->ex_groups);
 	np->netc_anon->cr_prison = &prison0;
 	prison_hold(np->netc_anon->cr_prison);
 	np->netc_numsecflavors = argp->ex_numsecflavors;
@@ -512,8 +506,8 @@ vfs_export_lookup(struct mount *mp, struct sockaddr *n
  */
 
 int 
-vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
-    struct ucred **credanonp, int *numsecflavors, int **secflavors)
+vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, uint64_t *extflagsp,
+    struct ucred **credanonp, int *numsecflavors, int *secflavors)
 {
 	struct netcred *np;
 
@@ -534,8 +528,9 @@ vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam
 		KASSERT(*numsecflavors < MAXSECFLAVORS,
 		    ("%s: numsecflavors >= MAXSECFLAVORS", __func__));
 	}
-	if (secflavors)
-		*secflavors = np->netc_secflavors;
+	if (secflavors && np->netc_numsecflavors > 0)
+		memcpy(secflavors, np->netc_secflavors, np->netc_numsecflavors *
+		    sizeof(int));
 	lockmgr(&mp->mnt_explock, LK_RELEASE, NULL);
 	return (0);
 }

Modified: head/sys/kern/vfs_init.c
==============================================================================
--- head/sys/kern/vfs_init.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/kern/vfs_init.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -268,8 +268,8 @@ vfs_fhtovp_sigdefer(struct mount *mp, struct fid *fidp
 }
 
 static int
-vfs_checkexp_sigdefer(struct mount *mp, struct sockaddr *nam, int *exflg,
-    struct ucred **credp, int *numsecflavors, int **secflavors)
+vfs_checkexp_sigdefer(struct mount *mp, struct sockaddr *nam, uint64_t *exflg,
+    struct ucred **credp, int *numsecflavors, int *secflavors)
 {
 	int prev_stops, rc;
 

Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/kern/vfs_mount.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -1041,11 +1041,13 @@ vfs_domount_update(
 	)
 {
 	struct export_args export;
+	struct o2export_args o2export;
 	struct vnode *rootvp;
 	void *bufp;
 	struct mount *mp;
-	int error, export_error, len;
+	int error, export_error, i, len;
 	uint64_t flag;
+	gid_t *grps;
 
 	ASSERT_VOP_ELOCKED(vp, __func__);
 	KASSERT((fsflags & MNT_UPDATE) != 0, ("MNT_UPDATE should be here"));
@@ -1128,11 +1130,66 @@ vfs_domount_update(
 		/* Assume that there is only 1 ABI for each length. */
 		switch (len) {
 		case (sizeof(struct oexport_args)):
-			bzero(&export, sizeof(export));
+			bzero(&o2export, sizeof(o2export));
+			o2export.ex_numsecflavors = 1;
+			o2export.ex_secflavors[0] = AUTH_SYS;
 			/* FALLTHROUGH */
+		case (sizeof(o2export)):
+			bcopy(bufp, &o2export, len);
+			export.ex_flags = (uint64_t)o2export.ex_flags;
+			export.ex_root = o2export.ex_root;
+			export.ex_uid = o2export.ex_anon.cr_uid;
+			export.ex_groups = NULL;
+			export.ex_ngroups = o2export.ex_anon.cr_ngroups;
+			if (export.ex_ngroups > 0) {
+				if (export.ex_ngroups <= XU_NGROUPS) {
+					export.ex_groups = malloc(
+					    export.ex_ngroups * sizeof(gid_t),
+					    M_TEMP, M_WAITOK);
+					for (i = 0; i < export.ex_ngroups; i++)
+						export.ex_groups[i] =
+						  o2export.ex_anon.cr_groups[i];
+				} else
+					export_error = EINVAL;
+			} else if (export.ex_ngroups < 0)
+				export_error = EINVAL;
+			export.ex_addr = o2export.ex_addr;
+			export.ex_addrlen = o2export.ex_addrlen;
+			export.ex_mask = o2export.ex_mask;
+			export.ex_masklen = o2export.ex_masklen;
+			export.ex_indexfile = o2export.ex_indexfile;
+			export.ex_numsecflavors = o2export.ex_numsecflavors;
+			if (export.ex_numsecflavors < MAXSECFLAVORS) {
+				for (i = 0; i < export.ex_numsecflavors; i++)
+					export.ex_secflavors[i] =
+					    o2export.ex_secflavors[i];
+			} else
+				export_error = EINVAL;
+			if (export_error == 0)
+				export_error = vfs_export(mp, &export);
+			free(export.ex_groups, M_TEMP);
+			break;
 		case (sizeof(export)):
 			bcopy(bufp, &export, len);
-			export_error = vfs_export(mp, &export);
+			grps = NULL;
+			if (export.ex_ngroups > 0) {
+				if (export.ex_ngroups <= NGROUPS_MAX) {
+					grps = malloc(export.ex_ngroups *
+					    sizeof(gid_t), M_TEMP, M_WAITOK);
+					export_error = copyin(export.ex_groups,
+					    grps, export.ex_ngroups *
+					    sizeof(gid_t));
+					if (export_error == 0)
+						export.ex_groups = grps;
+				} else
+					export_error = EINVAL;
+			} else if (export.ex_ngroups == 0)
+				export.ex_groups = NULL;
+			else
+				export_error = EINVAL;
+			if (export_error == 0)
+				export_error = vfs_export(mp, &export);
+			free(grps, M_TEMP);
 			break;
 		default:
 			export_error = EINVAL;
@@ -2344,24 +2401,4 @@ kernel_vmount(int flags, ...)
 
 	error = kernel_mount(ma, flags);
 	return (error);
-}
-
-/*
- * Convert the old export args format into new export args.
- *
- * The old export args struct does not have security flavors.  Otherwise, the
- * structs are identical.  The default security flavor 'sys' is applied when
- * the given args export the filesystem.
- */
-void
-vfs_oexport_conv(const struct oexport_args *oexp, struct export_args *exp)
-{
-
-	bcopy(oexp, exp, sizeof(*oexp));
-	if (exp->ex_flags & MNT_EXPORTED) {
-		exp->ex_numsecflavors = 1;
-		exp->ex_secflavors[0] = AUTH_SYS;
-	} else {
-		exp->ex_numsecflavors = 0;
-	}
 }

Modified: head/sys/nlm/nlm_prot_impl.c
==============================================================================
--- head/sys/nlm/nlm_prot_impl.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/nlm/nlm_prot_impl.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -1735,7 +1735,8 @@ static int
 nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp,
     fhandle_t *fhp, struct vfs_state *vs, accmode_t accmode)
 {
-	int error, exflags;
+	int error;
+	uint64_t exflags;
 	struct ucred *cred = NULL, *credanon = NULL;
 	
 	memset(vs, 0, sizeof(*vs));

Modified: head/sys/sys/mount.h
==============================================================================
--- head/sys/sys/mount.h	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/sys/mount.h	Sun Jun 14 00:10:18 2020	(r362158)
@@ -499,10 +499,10 @@ struct oexport_args {
 };
 
 /*
- * Export arguments for local filesystem mount calls.
+ * Not quite so old export arguments with 32bit ex_flags and xucred ex_anon.
  */
 #define	MAXSECFLAVORS	5
-struct export_args {
+struct o2export_args {
 	int	ex_flags;		/* export related flags */
 	uid_t	ex_root;		/* mapping for root uid */
 	struct	xucred ex_anon;		/* mapping for anonymous user */
@@ -516,6 +516,25 @@ struct export_args {
 };
 
 /*
+ * Export arguments for local filesystem mount calls.
+ */
+#define	MAXSECFLAVORS	5
+struct export_args {
+	uint64_t ex_flags;		/* export related flags */
+	uid_t	ex_root;		/* mapping for root uid */
+	uid_t	ex_uid;			/* mapping for anonymous user */
+	int	ex_ngroups;
+	gid_t	*ex_groups;
+	struct	sockaddr *ex_addr;	/* net address to which exported */
+	u_char	ex_addrlen;		/* and the net address length */
+	struct	sockaddr *ex_mask;	/* mask of valid bits in saddr */
+	u_char	ex_masklen;		/* and the smask length */
+	char	*ex_indexfile;		/* index file for WebNFS URLs */
+	int	ex_numsecflavors;	/* security flavor count */
+	int	ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
+};
+
+/*
  * Structure holding information for a publicly exported filesystem
  * (WebNFS). Currently the specs allow just for one such filesystem.
  */
@@ -694,8 +713,8 @@ typedef	int vfs_vget_t(struct mount *mp, ino_t ino, in
 typedef	int vfs_fhtovp_t(struct mount *mp, struct fid *fhp,
 		    int flags, struct vnode **vpp);
 typedef	int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam,
-		    int *extflagsp, struct ucred **credanonp,
-		    int *numsecflavors, int **secflavors);
+		    uint64_t *extflagsp, struct ucred **credanonp,
+		    int *numsecflavors, int *secflavors);
 typedef	int vfs_init_t(struct vfsconf *);
 typedef	int vfs_uninit_t(struct vfsconf *);
 typedef	int vfs_extattrctl_t(struct mount *mp, int cmd,
@@ -928,8 +947,6 @@ void	vfs_mount_error(struct mount *, const char *, ...
 void	vfs_mountroot(void);			/* mount our root filesystem */
 void	vfs_mountedfrom(struct mount *, const char *from);
 void	vfs_notify_upper(struct vnode *, int);
-void	vfs_oexport_conv(const struct oexport_args *oexp,
-	    struct export_args *exp);
 void	vfs_ref(struct mount *);
 void	vfs_rel(struct mount *);
 struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *,

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c	Sat Jun 13 23:35:22 2020	(r362157)
+++ head/sys/ufs/ffs/ffs_vfsops.c	Sun Jun 14 00:10:18 2020	(r362158)
@@ -596,7 +596,6 @@ static int
 ffs_cmount(struct mntarg *ma, void *data, uint64_t flags)
 {
 	struct ufs_args args;
-	struct export_args exp;
 	int error;
 
 	if (data == NULL)
@@ -604,10 +603,9 @@ ffs_cmount(struct mntarg *ma, void *data, uint64_t fla
 	error = copyin(data, &args, sizeof args);
 	if (error)
 		return (error);
-	vfs_oexport_conv(&args.export, &exp);
 
 	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
-	ma = mount_arg(ma, "export", &exp, sizeof(exp));
+	ma = mount_arg(ma, "export", &args.export, sizeof(args.export));
 	error = kernel_mount(ma, flags);
 
 	return (error);


More information about the svn-src-all mailing list