User Tools

Site Tools


chroot

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

chroot [2010/04/15 21:18] (current)
Line 1: Line 1:
  
 +
 +**Chroot is largely a neat semantic hack that has come to be expected on Unix systems. Simply, when chroot is called with a pathname, that pathname becomes '/'​ for the process and it's descendants. Nothing more, nothing less.**
 +
 +It is worth noting that since it IS a semantic hack that was never originally envisioned as a security measure, several holes exist in it. It is also notable that many use chroot as a security measure, and it is even becoming part of 'best practices'​ for some daemons, particularly those that have been security problems in the past or that are frequently ​  ​targets of attack.
 +
 +In Linux, chroot is implemented entirely within path name lookup functions. That's reasonable since it is primarily a semantic hack. Simply, the __user_walk function accepts a path name string and performs a series of lookups within the VFS to return a dentry (a file system object more or less). ​
 +
 +To implement chroot semantics, when it handles a leading '/',​ it substitutes in the dentry of the process'​s chroot. As it walks through the path, if it encounters '​..'​ while already at the process'​s chroot, it skips that element (which is   also a necessary behaviour when it is at the real root of the filesystem lest it walk off into space).
 +
 +When a path contains no leading '/',​ it begins it's walk with the dentry for the current directory (cwd) which is also stored in a process'​s task structure.
 +
 +The chroot system call does nothing but replace the root dentry in a process'​s task struct with the dentry for the specified path. A nice elegant system that avoids wasting time actually checking for corner cases including if the process is chrooted at all.
 +
 +Unfortunately,​ this leads to a hole in chroot. The call to chroot does NOT change the CWD dentry for the process. This means that the process can hold on to a live dentry that is above the root dentry. The process may then chdir to a path consisting of a long series of '​../'​ to end up at the real root of the filesystem. ​
 +
 +do_path_lookup won't complain since it will never encounter the process'​s root dentry. Then, the process calls chroot('​.'​) to reset it's root dentry to be the real root of the filesystem. Since chroot has no memory for previous root paths at all, a process doing that escapes form the '​jail'​ it was in and has the run of the system.
 +
 +For an example, lets say a process running as root has been chrooted into /​jail/​virtual1 and it is at that root. This gives:
 +
 +        real CWD = '/​jail/​virtual1'​
 +        apparent CWD = '/'​
 +        chroot = '/​jail/​virtual1'​
 +
 +It now does:
 +        mkdir('​cake'​)
 + real cwd = '/​jail/​virtual1'​
 + apparent cwd = '/'​
 + chroot = '/​jail/​virtual1'​
 +
 +   ​chroot('​cake'​)
 + real cwd = '/​jail/​virtual1'​
 + apparent cwd = '/​jail/​virtual1'​
 + chroot = '/​jail/​virtual1/​cake'​
 +
 +   ​chdir('​../​../​../​../​..'​)
 + real cwd = '/'​
 + apparent cwd = '/'​
 + chroot = '/​jail/​virtual1/​cake'​
 +
 +   ​chroot('​.'​)
 + real cwd = '/'​
 + apparent cwd = '/'​
 + chroot = '/'​
 +
 +
 +In response, as a hack on top of a hack, chroot is now generally limited to root (or CAP_SYS_CHROOT on capabilities systems) and daemons in a chroot jail are expected to run as non-root (a good idea anyway). The escape from chroot isn't fixed, but is restricted to root. Of course, the security of that measure depends entirely on a system with no local root exploits, including no exploitable suid root programs in the jail.
 +
 +As we should all know, when it comes to security, those are not the best assumptions to be making.
 +
 +The key to this 'get out of jail free card' is having a cwd outside of the jail.
 +The escape above is widely publicized on security sites, but still oddly obscure elsewhere. However, the situation is actually worse than that.
 +
 +In many UNIX systems (Linux included), one process may pass open file descriptors to another through a UNIX socket. An open file descriptor can be used to set the CWD through the fchdir system call. So, a non-root process can access files outside of it's chroot if it can get a little help from another non-root process that lives outside of the jail (even if the second process is itself in a jail above the escaping process).
 +
 +The escape available for non-root processes is somewhat limited in that paths with a leading '/'​ will still refer to it's jail, but it can do plenty of damage using relative pathnames.
 +
 +  Consider, a jail is set up in /​jails/​virtual1.
 +  Further, a sub-jail is created in /​jails/​virtual1/​subjails/​virtual2.
 +
 +  Alice lives in /​jails/​virtual1.
 +  Bob has subverted a daemon chrooted to /​jails/​virtual1/​subjails/​virtual2.
 +
 +  Alice opens an fd to her '/'​ directory which is actually /​jails/​virtual1.
 +  Alice creates a unix socket named '/​subjails/​virtual2/​cake'​
 +
 +  Bob connects to /cake.
 +  Alice passes bob her open directory.
 +
 +  Bob calls fchdir on that open directory. He now sees his pwd as '/​jails/​virtual1'​!!!
 +
 +  Bob calls chdir("​../​.."​). His CWD is now the REAL ROOT OF THE FILESYSTEM.
 +
 +  As an added touch, Bob can now boost Alice out of jail as well.
 +
 +If either Bob or Alice have the necessary libraries within their chroot jail, they can potentially exploit a suid root binary in the real root filesystem to complete their escape. Otherwise, they STILL have a lot of access to the system that they were not intended to have. If the sysadmin was relying on chroot to keep them out, security in the real '/'​ may not be all it should be.
 +
 +It really doesn'​t matter that chroot isn't '​officially'​ defined as a security measure. It IS USED as one all the time and is even coming to be accepted as a best practice. For example, by default, Fedora places named in a chroot jail now.
 +
 +The Groucho Marx approach of 'so don't do that' will not do. Chroot is becoming popular exactly because it is a useful functionality provided that these holes are closed.
 +
 +The harden_chroot patch does exactly that. Simply, the patch causes chroot to ALSO chdir to the specified directory. In addition, it adds a function that walks upwards from any dentry until it either encounters the process'​s root or the real filesystem root. That check is called by fchdir and the path lookup functions. If the process root is not encountered,​ the system call fails, so that having an open descriptor or CWD outside of your root is no longer useful for escaping from jail.
 +
 +This patch MAY cause unexpected results IF some program depended on being passed an open directory outside of it's jail, but given that such a procedure renders chroot practically useless, it probably deserves to fail! The correct way to give a chroot program access to an additional directory is to bind mount it inside the jail.
 +
 +Systems depending on passing open regular files or devices to a jailed program will continue to function normally.
 +
 + --- //​[[pyro@linux.edu|Steven James]] 2007/01/13 12:54//
chroot.txt ยท Last modified: 2010/04/15 21:18 (external edit)