Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Nov 1996 22:57:27 +1030 (CST)
From:      newton@communica.com.au (Mark Newton)
To:        newton@communica.com.au (Mark Newton)
Cc:        karpen@ocean.campus.luth.se, newton@communica.com.au, freebsd-security@FreeBSD.org
Subject:   Re: chroot() security
Message-ID:  <9611051227.AA23882@communica.com.au>
In-Reply-To: <9611051004.AA21746@communica.com.au> from "Mark Newton" at Nov 5, 96 08:34:32 pm

next in thread | previous in thread | raw e-mail | index | archive | help
Mark Newton wrote:

 > And, if they require the added security and can't comprehend the source
 > code then no accusations of intellectual snobbery will convince me that
 > they are the *wrong* people to be looking after their security.
        ^^^aren't!

Sense change:  I hope I don't write code like that :-)

 > I think we are trying.  I have a patch here which I'm testing at the
 > moment;  I'll release it to this list later tonight if I'm happy with
 > it. 

Ok, here's a patch.  Comment to your heart' desires.

To use it:  Apply the patch by using "patch < filename" (beware: 
absolute filenames in the patch;  You may want to edit the headers if
your source tree doesn't live in /usr/src and your kernel source
isn't reachable as /sys).  Edit your kernel config file;  add a line which 
looks like:

options "FUNKY_CHROOT"

config, make depend, make, make install, reboot.  Woo-hoo!

I tested it by using a diskless root filesystem I have lying about
on one of my disks:  Without the patch, the following works:

  atdot# chroot /export/root/dotat /bin/csh
  dotat# chroot . /bin/csh
  dotat#

With the patch, I get this:

  atdot# chroot /export/root/dotat /bin/csh
  dotat# chroot . /bin/csh
  chroot: .: Operation not permitted
  dotat# 

I've done a few more tests and they seem to work ok;  let me know if
this is broken (it's fairly simple, but who knows?)

   - mark

---
Mark Newton                               Email: newton@communica.com.au
Systems Engineer                          Phone: +61-8-8373-2523
Communica Systems                         WWW:   http://www.communica.com.au



*** /usr/src/lib/libc/sys/chroot.2.orig	Tue Nov  5 20:55:43 1996
--- /usr/src/lib/libc/sys/chroot.2	Tue Nov  5 22:27:49 1996
***************
*** 60,65 ****
--- 60,71 ----
  has no effect on the process's current directory.
  .Pp
  This call is restricted to the super-user.
+ .Pp
+ If the kernel has been built with the FUNKY_CHROOT compile-time option,
+ then calling chroot(2) will cause all future invocations for the calling
+ process and all of its future children to fail.  In certain circumstances
+ this behaviour can enhance security;  In other circumstances it can
+ reduce security and cause existing software to break horribly.
  .Sh RETURN VALUES
  Upon successful completion, a value of 0 is returned.  Otherwise,
  a value of -1 is returned and
***************
*** 72,78 ****
  .It Bq Er ENOTDIR
  A component of the path name is not a directory.
  .It Bq Er EPERM
! The effective user ID is not the super-user.
  .It Bq Er EINVAL
  The pathname contains a character with the high-order bit set.
  .It Bq Er ENAMETOOLONG
--- 78,87 ----
  .It Bq Er ENOTDIR
  A component of the path name is not a directory.
  .It Bq Er EPERM
! The effective user ID is not the super-user, or this kernel has been
! built with FUNKY_CHROOT and a previous call to
! .Xr chroot 2
! has been made by the caller or one of its ancestors.
  .It Bq Er EINVAL
  The pathname contains a character with the high-order bit set.
  .It Bq Er ENAMETOOLONG
***************
*** 90,95 ****
--- 99,106 ----
  .It Bq Er EIO
  An I/O error occurred while reading from or writing to the file system.
  .El
+ .Sh BUGS
+ FUNKY_CHROOT is a stupid name.
  .Sh SEE ALSO
  .Xr chdir 2
  .Sh HISTORY
*** /sys/kern/vfs_syscalls.c.orig	Tue Nov  5 18:20:22 1996
--- /sys/kern/vfs_syscalls.c	Tue Nov  5 20:42:21 1996
***************
*** 607,612 ****
--- 607,619 ----
  	register struct filedesc *fdp = p->p_fd;
  	int error;
  	struct nameidata nd;
+ #if defined(FUNKY_CHROOT)
+ 	register struct proc *init;
+ 
+ 	init = pfind((pid_t)1);   /* locate init's proc structure */
+ 	if (fdp->fd_rdir != init->p_fd->fd_rdir)
+ 		return(EPERM);	  /* if p's root != init's root return EPERM */
+ #endif /* FUNKY_CHROOT */
  
  	error = suser(p->p_ucred, &p->p_acflag);
  	if (error)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9611051227.AA23882>