Home | Comics | wishlist | Impressum | Datenschutzerklärung | 54.163.42.154


For root to escape the prison, the system must have one of the following:

I'd say that chroot jails would definitely be a problem for the script kiddies to maneuver around, and for that matter, most everyone else who should try to circumvent them.

chroot("pathname") does not make "pathname" the current directory. If the caller (who usually must have special privileges) is not *in* "pathname" or some descendant thereof, then after the chroot() call the caller is still not imprisoned.
Therafter *relative* pathnames will be calculated outside the chroot prison until such time as the relative path, in it's interpretation, enters the prison (see examples below). Absolute pathnames, will, of course, immediately after the chroot() call, be interpreted relative to the new root. Another important item to keep in mind is that all previously open file descriptors remain open and valid.
So, if a caller opens the directory "/etc", then calls chroot("/daemon/root"), then calls chdir("/") he will be in the physical directory "/daemon/root", which will appear to him to be "/".
At that point he has no access, via pathnames, to anything outside of the chroot prison. *However*, he may still call fchdir() with the open file descriptor on "/etc", and his physical and apparent directory will thereafter be "/etc".
The *only* way to temporarily change the current root and then change it back is to keep an open file descriptor on "/", (marked close on exec!) chroot() to a prison, fork a child that you *know* will exec, and then the parent can call fchroot() with the "/" file descriptor and regain it's access to the entire filesystem while the child is left in it's prison.
I do *not* believe that even root, once in a chroot prison, can chdir("../../../") out of it! I also firmly believe that if the caller of chroot() is situated within the hierarchy rooted by the argument thereto when making that call, the caller is imprisoned upon the return thereof.

Example of relative pathname resolution from outside to within a chroot prison:

  getcwd() returns: "/usr/daemon/bin"
  chroot("/usr/daemon/root");
  getcwd() still returns: "/usr/daemon/bin"
  chdir("../../spool/mqueue");
  getcwd() returns: "/usr/spool/mqueue" and means the real "/usr/spool/mqueue"
  chdir("../../daemon/root/../bin");
  getcwd() returns: "/bin" and means the imprisoned "/usr/daemon/root/bin"

E.g., passing into /usr/daemon/root even while interpreting a single relative pathname rooted *outside* the prison results in imprisonment (of that pathname: it could have just been a file open, not a chdir()).
This all works because current working directories and current roots are stored as special file descriptors in the kernel. I can explain if needed.
Also, in case I wasn't clear above, the pathname argument to chroot() is interpreted in the context of the current root. Gaining root access within a prison does *not* mean that you can simply chroot() out of the prison. If there are extrapenitential open directory file descriptors inherited from before the original chroot() occurred, becoming root would allow one to call fchroot() thereupon and change the prison in which one is contained.

References

Some more comments

There are lots of other ways for root to escape from a chroot jail. For example:

and so on.

Moreover, note that chrooted root processes can do lots of other harm: kill all the rest of the processes on the box, set the time of day, set the local hostname, reboot your machine, use sysctl to turn on some dangerous option (e.g., IP forwarding), renice other processes, and the like. This is probably not so good, either.

Chroot is a lot better than nothing, but it doesn't provide a secure jail, especially not for root. However, the following tools are intended to provide a secure jail, and may be of interest to you:

I think you may find it of interest.


© by Ralf Hildebrandt
This document contains links to external information sources that I do neither monitor nor control. I explicitly disclaim any liabilities in respect to external references.
You are getting this document without any guarantees. Any methods shown above are meant as demonstration and may be wrong in some place. You may damage your system if you try to follow my hints and instructions. You do this at your own risk!

This file was last modified 26. Apr 2007 by root