svn commit: r224614 - head/sys/kern

Martin Matuska mm at FreeBSD.org
Tue Aug 2 19:13:57 UTC 2011


Author: mm
Date: Tue Aug  2 19:13:56 2011
New Revision: 224614
URL: http://svn.freebsd.org/changeset/base/224614

Log:
  For mount, discover f_mntonname from supplied path argument
  using vn_fullpath_global(). This fixes f_mntonname if mounting
  inside chroot, jail or with relative path as argument.
  
  For unmount in jail, use vn_fullpath_global() to discover
  global path from supplied path argument. This fixes unmount in jail.
  
  Reviewed by:	pjd, kib
  Approved by:	re (kib)
  MFC after:	2 weeks

Modified:
  head/sys/kern/vfs_mount.c

Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c	Tue Aug  2 18:12:19 2011	(r224613)
+++ head/sys/kern/vfs_mount.c	Tue Aug  2 19:13:56 2011	(r224614)
@@ -745,7 +745,6 @@ static int
 vfs_domount_first(
 	struct thread *td,		/* Calling thread. */
 	struct vfsconf *vfsp,		/* File system type. */
-	char *fspath,			/* Mount path. */
 	struct vnode *vp,		/* Vnode to be covered. */
 	int fsflags,			/* Flags common to all filesystems. */
 	struct vfsoptlist **optlist	/* Options local to the filesystem. */
@@ -754,12 +753,25 @@ vfs_domount_first(
 	struct vattr va;
 	struct mount *mp;
 	struct vnode *newdp;
+	char *fspath, *fbuf;
 	int error;
 
 	mtx_assert(&Giant, MA_OWNED);
 	ASSERT_VOP_ELOCKED(vp, __func__);
 	KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here"));
 
+	/* Construct global filesystem path from vp. */
+	error = vn_fullpath_global(td, vp, &fspath, &fbuf);
+	if (error != 0) {
+		vput(vp);
+		return (error);
+	}
+	if (strlen(fspath) >= MNAMELEN) {
+		vput(vp);
+		free(fbuf, M_TEMP);
+		return (ENAMETOOLONG);
+	}
+
 	/*
 	 * If the user is not root, ensure that they own the directory
 	 * onto which we are attempting to mount.
@@ -781,12 +793,14 @@ vfs_domount_first(
 	}
 	if (error != 0) {
 		vput(vp);
+		free(fbuf, M_TEMP);
 		return (error);
 	}
 	VOP_UNLOCK(vp, 0);
 
 	/* Allocate and initialize the filesystem. */
 	mp = vfs_mount_alloc(vp, vfsp, fspath, td->td_ucred);
+	free(fbuf, M_TEMP);
 	/* XXXMAC: pass to vfs_mount_alloc? */
 	mp->mnt_optnew = *optlist;
 	/* Set the mount level flags. */
@@ -1069,12 +1083,10 @@ vfs_domount(
 		mtx_lock(&Giant);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vp = nd.ni_vp;
-	if ((fsflags & MNT_UPDATE) == 0) {
-		error = vfs_domount_first(td, vfsp, fspath, vp, fsflags,
-		    optlist);
-	} else {
+	if ((fsflags & MNT_UPDATE) == 0)
+		error = vfs_domount_first(td, vfsp, vp, fsflags, optlist);
+	else
 		error = vfs_domount_update(td, vp, fsflags, optlist);
-	}
 	mtx_unlock(&Giant);
 
 	ASSERT_VI_UNLOCKED(vp, __func__);
@@ -1105,7 +1117,8 @@ unmount(td, uap)
 	} */ *uap;
 {
 	struct mount *mp;
-	char *pathbuf;
+	struct nameidata nd;
+	char *pathbuf, *rpathbuf, *fbuf;
 	int error, id0, id1;
 
 	AUDIT_ARG_VALUE(uap->flags);
@@ -1140,6 +1153,28 @@ unmount(td, uap)
 		mtx_unlock(&mountlist_mtx);
 	} else {
 		AUDIT_ARG_UPATH1(td, pathbuf);
+		/*
+		 * If we are jailed and this is not a root jail try to find
+		 * global path for path argument.
+		 */
+		if (jailed(td->td_ucred) &&
+		    td->td_ucred->cr_prison->pr_root != rootvnode) {
+			NDINIT(&nd, LOOKUP,
+			    FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
+			    UIO_SYSSPACE, pathbuf, td);
+			if (namei(&nd) == 0) {
+				NDFREE(&nd, NDF_ONLY_PNBUF);
+				if (vn_fullpath_global(td, nd.ni_vp, &rpathbuf,
+				    &fbuf) == 0) {
+					if (strlen(rpathbuf) < MNAMELEN) {
+						strlcpy(pathbuf, rpathbuf,
+						    MNAMELEN);
+					}
+					free(fbuf, M_TEMP);
+				}
+				vput(nd.ni_vp);
+			}
+		}
 		mtx_lock(&mountlist_mtx);
 		TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
 			if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)


More information about the svn-src-all mailing list