DragonFly BSD
DragonFly submit List (threaded) for 2005-02
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

getfsstat visibility patch


From: Joerg Sonnenberger <joerg@xxxxxxxxxxxxxxxxx>
Date: Wed, 2 Feb 2005 01:00:37 +0100
Mail-followup-to: submit@crater.dragonflybsd.org

Hi all,
attached patch changes getfsstat to only show filesystems
under the current chroot() path (or the jail root, if jailed, but
not chrooted).

A side effect is that the following works:
mkdir /mnt/test
mount -t procfs proc /mnt/test
mv /mnt /mnt2
umount /mnt2/test

This doesn't even work on Linux :)

Joerg
Index: vfs_syscalls.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.57
diff -u -r1.57 vfs_syscalls.c
--- vfs_syscalls.c	1 Feb 2005 21:52:11 -0000	1.57
+++ vfs_syscalls.c	1 Feb 2005 23:46:32 -0000
@@ -892,6 +892,37 @@
 	return (error);
 }
 
+static int
+chroot_visible_mnt(struct mount *mp, struct proc *p)
+{
+	struct namecache *ncp;
+	/*
+	 * First check if this file system is below
+	 * the chroot path.
+	 */
+	ncp = mp->mnt_ncp;
+	while (ncp != NULL && ncp != p->p_fd->fd_nrdir)
+		ncp = ncp->nc_parent;
+	if (ncp == NULL) {
+		/*
+		 * This is not below the chroot path.
+		 *
+		 * Check if the chroot path is on the same filesystem,
+		 * by determing if we have to cross a mount point
+		 * before reaching mp->mnt_ncp.
+		 */
+		ncp = p->p_fd->fd_nrdir;
+		while (ncp != NULL && ncp != mp->mnt_ncp) {
+			if (ncp->nc_flag & NCF_MOUNTPT) {
+				ncp = NULL;
+				break;
+			}
+			ncp = ncp->nc_parent;
+		}
+	}
+	return(ncp != NULL);
+}
+
 /*
  * getfsstat_args(struct statfs *buf, long bufsize, int flags)
  *
@@ -902,10 +933,18 @@
 getfsstat(struct getfsstat_args *uap)
 {
 	struct thread *td = curthread;
+	struct proc *p = td->td_proc;
 	struct mount *mp, *nmp;
 	struct statfs *sp, *sfsp;
 	lwkt_tokref ilock;
 	long count, maxcount, error;
+	int is_chrooted;
+	char *freepath, *fullpath;
+
+	if (p != NULL && (p->p_fd->fd_nrdir->nc_flag & NCF_ROOT) == 0)
+		is_chrooted = 1;
+	else
+		is_chrooted = 0;
 
 	maxcount = uap->bufsize / sizeof(struct statfs);
 	sfsp = uap->buf;
@@ -917,6 +956,12 @@
 			continue;
 		}
 		if (sfsp && count < maxcount) {
+			if (is_chrooted && !chroot_visible_mnt(mp, p)) {
+				lwkt_gettokref(&ilock);
+				nmp = TAILQ_NEXT(mp, mnt_list);
+				vfs_unbusy(mp, td);
+				continue;
+			}
 			sp = &mp->mnt_stat;
 			/*
 			 * If MNT_NOWAIT or MNT_LAZY is specified, do not
@@ -932,6 +977,15 @@
 				continue;
 			}
 			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+
+			error = cache_fullpath(p, mp->mnt_ncp, &fullpath, &freepath);
+			if (error)
+				return(error);
+			bzero(sp->f_mntonname, sizeof(sp->f_mntonname));
+			strlcpy(sp->f_mntonname, fullpath,
+				sizeof(sp->f_mntonname));
+			free(freepath, M_TEMP);
+
 			error = copyout(sp, sfsp, sizeof(*sp));
 			if (error) {
 				vfs_unbusy(mp, td);


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]