Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/vfs_lookup.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/vfs_lookup.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.39 retrieving revision 1.40 diff -u -p -r1.39 -r1.40 --- src/sys/kern/vfs_lookup.c 2001/12/08 04:09:59 1.39 +++ src/sys/kern/vfs_lookup.c 2002/06/21 02:19:12 1.40 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lookup.c,v 1.39 2001/12/08 04:09:59 lukem Exp $ */ +/* $NetBSD: vfs_lookup.c,v 1.40 2002/06/21 02:19:12 wrstuden Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.39 2001/12/08 04:09:59 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.40 2002/06/21 02:19:12 wrstuden Exp $"); #include "opt_ktrace.h" @@ -57,6 +57,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c #include #include #include +#include #ifdef KTRACE #include @@ -435,6 +436,8 @@ dirloop: * 1. If at root directory (e.g. after chroot) * or at absolute root directory * then ignore it so can't get out. + * 1a. If we have somehow gotten out of a jail, warn + * and also ignore it so we can't get farther out. * 2. If this vnode is the root of a mounted * filesystem, then replace it with the * vnode which was mounted on so we take the @@ -448,6 +451,31 @@ dirloop: VREF(dp); goto nextname; } + if (ndp->ni_rootdir != rootvnode) { + int retval; + VOP_UNLOCK(dp, 0); + retval = vn_isunder(dp, ndp->ni_rootdir, + cnp->cn_proc); + vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); + if (!retval) { + /* Oops! We got out of jail! */ + log(LOG_WARNING, + "chrooted pid %d uid %d (%s) " + "detected outside of its chroot\n", + cnp->cn_proc->p_pid, + cnp->cn_proc->p_ucred->cr_uid, + cnp->cn_proc->p_comm); + /* Put us at the jail root. */ + vput(dp); + dp = ndp->ni_rootdir; + ndp->ni_dvp = dp; + ndp->ni_vp = dp; + VREF(dp); + VREF(dp); + vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); + goto nextname; + } + } if ((dp->v_flag & VROOT) == 0 || (cnp->cn_flags & NOCROSSMOUNT)) break;