From 2fe5bd8bb8393100f5e0a994aed45a9a16616070 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Sat, 25 Sep 1999 14:14:21 +0000 Subject: [PATCH] Fix a hole in jail(2). Noticed by: Alexander Bezroutchko --- sys/kern/kern_descrip.c | 7 +++++++ sys/kern/vfs_extattr.c | 4 ++++ sys/kern/vfs_lookup.c | 7 ++++++- sys/kern/vfs_syscalls.c | 4 ++++ sys/sys/filedesc.h | 1 + sys/sys/namei.h | 1 + sys/sys/param.h | 2 +- 7 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 45f09457945a..fa0b4df41f96 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -885,6 +885,9 @@ fdinit(p) VREF(newfdp->fd_fd.fd_cdir); newfdp->fd_fd.fd_rdir = fdp->fd_rdir; VREF(newfdp->fd_fd.fd_rdir); + newfdp->fd_fd.fd_jdir = fdp->fd_jdir; + if (newfdp->fd_fd.fd_jdir) + VREF(newfdp->fd_fd.fd_jdir); /* Create the file descriptor table. */ newfdp->fd_fd.fd_refcnt = 1; @@ -932,6 +935,8 @@ fdcopy(p) bcopy(fdp, newfdp, sizeof(struct filedesc)); VREF(newfdp->fd_cdir); VREF(newfdp->fd_rdir); + if (newfdp->fd_jdir) + VREF(newfdp->fd_jdir); newfdp->fd_refcnt = 1; /* @@ -995,6 +1000,8 @@ fdfree(p) FREE(fdp->fd_ofiles, M_FILEDESC); vrele(fdp->fd_cdir); vrele(fdp->fd_rdir); + if(fdp->fd_jdir) + vrele(fdp->fd_jdir); FREE(fdp, M_FILEDESC); } diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index e5354f6d5a7c..952f875ec49e 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -910,6 +910,10 @@ chroot(p, uap) return (error); vrele(fdp->fd_rdir); fdp->fd_rdir = nd.ni_vp; + if (!fdp->fd_jdir) { + fdp->fd_jdir = nd.ni_vp; + VREF(fdp->fd_jdir); + } return (0); } diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index e168ce58c18d..39c46e88bace 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -130,6 +130,7 @@ namei(ndp) * Get starting point for the translation. */ ndp->ni_rootdir = fdp->fd_rdir; + ndp->ni_topdir = fdp->fd_jdir; dp = fdp->fd_cdir; VREF(dp); @@ -387,10 +388,14 @@ dirloop: * filesystem, then replace it with the * vnode which was mounted on so we take the * .. in the other file system. + * 3. If the vnode is the top directory of + * the jail or chroot, don't let them out. */ if (cnp->cn_flags & ISDOTDOT) { for (;;) { - if (dp == ndp->ni_rootdir || dp == rootvnode) { + if (dp == ndp->ni_rootdir || + dp == ndp->ni_topdir || + dp == rootvnode) { ndp->ni_dvp = dp; ndp->ni_vp = dp; VREF(dp); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index e5354f6d5a7c..952f875ec49e 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -910,6 +910,10 @@ chroot(p, uap) return (error); vrele(fdp->fd_rdir); fdp->fd_rdir = nd.ni_vp; + if (!fdp->fd_jdir) { + fdp->fd_jdir = nd.ni_vp; + VREF(fdp->fd_jdir); + } return (0); } diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 4505875fe5c4..d27611209517 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -61,6 +61,7 @@ struct filedesc { char *fd_ofileflags; /* per-process open file flags */ struct vnode *fd_cdir; /* current directory */ struct vnode *fd_rdir; /* root directory */ + struct vnode *fd_jdir; /* jail root directory */ int fd_nfiles; /* number of open files allocated */ u_short fd_lastfile; /* high-water mark of fd_ofiles */ u_short fd_freefile; /* approx. next free file */ diff --git a/sys/sys/namei.h b/sys/sys/namei.h index c4611d9c3fc4..364b0012b370 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -58,6 +58,7 @@ struct nameidata { /* struct ucred *ni_cred; credentials */ struct vnode *ni_startdir; /* starting directory */ struct vnode *ni_rootdir; /* logical root directory */ + struct vnode *ni_topdir; /* logical top directory */ /* * Results: returned from/manipulated by lookup */ diff --git a/sys/sys/param.h b/sys/sys/param.h index b61279471c54..ff68a0758f38 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -46,7 +46,7 @@ #define BSD4_3 1 #define BSD4_4 1 #undef __FreeBSD_version -#define __FreeBSD_version 400009 /* Master, propagated to newvers */ +#define __FreeBSD_version 400010 /* Master, propagated to newvers */ #ifndef NULL #define NULL 0