From owner-freebsd-current Thu Sep 21 13:30:39 1995 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id NAA27649 for current-outgoing; Thu, 21 Sep 1995 13:30:39 -0700 Received: from phaeton.artisoft.com (phaeton.Artisoft.COM [198.17.250.211]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id NAA27641 for ; Thu, 21 Sep 1995 13:30:36 -0700 Received: (from terry@localhost) by phaeton.artisoft.com (8.6.11/8.6.9) id NAA26779 for current@freebsd.org; Thu, 21 Sep 1995 13:29:21 -0700 From: Terry Lambert Message-Id: <199509212029.NAA26779@phaeton.artisoft.com> Subject: chroot wierdness in namei() To: current@freebsd.org Date: Thu, 21 Sep 1995 13:29:21 -0700 (MST) X-Mailer: ELM [version 2.4 PL24] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Length: 2166 Sender: owner-current@freebsd.org Precedence: bulk In the lookup() function callwd by namei() in vfs_lookup.c, the following loop is present for processing "..": if (cnp->cn_flags & ISDOTDOT) { for (;;) { *** if (dp == ndp->ni_rootdir || dp == rootvnode) { ndp->ni_dvp = dp; ndp->ni_vp = dp; VREF(dp); goto nextname; } if ((dp->v_flag & VROOT) == 0 || (cnp->cn_flags & NOCROSSMOUNT)) break; tdp = dp; dp = dp->v_mount->mnt_vnodecovered; vput(tdp); VREF(dp); VOP_LOCK(dp); } } In the line marked "***", does anyone else think the "dp == rootvnode" check is bogus? In the namei() that calls it, the following code is used: /* * Get starting point for the translation. */ if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL) ndp->ni_rootdir = rootvnode; dp = fdp->fd_cdir; VREF(dp); The only failure case I see is: I) A security hole is exercised: 1) open 'dir' 2) chroot to subtree not containing 'dir' 3) fchdir() to 'dir' (making the current directory outside the chrooted heirarchy). 4) use a relative path containing ".." from there causing an attempt at a ".." traversal of the real "/". II) A directory hard link transits out of the chroot'ed subgraph. It seems this would be a security hole in any case, right? I could write a program to open an fd for a dir and turn off close on exec and then run an suid program that chroot'ed me and then sneak out. Right? I mean one could use the "play" chroot() suggested in the hack sources or an SUID perl script (using "secure" perl) or any of a number of tools for doing things like administering your personal area of a public FTP server. Perhaps fd's open to VDIR vnodes should be closed on chroot(2)? It's not like chroot()'ing is a reversable process (well, unless you have an fd to a dir out of the chrooted'ed hierarchy and use it to call chroot again to chroot to "/". 8-)), so perhaps this hole should be plugged? And then the check for rootvnode removed from lookup()? Directory hard links should be an error in any case (needs fixed). Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.