看板 DFBSD_submit 關於我們 聯絡資訊
--HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="getfsstat_visibility.patch" 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); --HcAYCG3uE/tztfnV--