On Thu, Mar 15, 2001 at 10:15:57AM -0700, Ray Percival wrote: > Not knowing about *BSD's jails I'm not sure if you want to > restrict a user to only one part of the filesystem why not use > chroot?
Because root can break out of a chroot(). Trivially. It's not related to devices, like some seem to think... the method is even simpler: #define MY_JAIL_PATH "/whatever/you/want" chdir( MY_JAIL_PATH ); chroot( MY_JAIL_PATH ); /* process is now supposedly jailed */ /* can we get out? sure.... we have the keys cause we're root.... */ mkdir( MY_JAIL_PATH "/escape" ); /* did I mention I love ANSI C's string concatenation? */ chroot( MY_JAIL_PATH "/escape" ); /* now, at this point, we're chrooted to /whatever/you/want/escape... but our current directory is /whatever/you/want.... */ /* let's go up a bit.... */ chdir ("../../../../../../../../../.." ); /* should be plenty, if not we can just repeat it... */ chroot ( "." ); And, like magic, we're out of jail. Yes, chroot is useful. It's VERY useful for programs that -drop- their privileges (and thus can't chroot() again to break out). But, in this case, the questioner wanted to allow root into the jail... you can't do that without destroying all the security that chroot gives you. It's not a panacea. Now, there are workarounds: the 'capabilities' of current kernels should allow you to grant root without granting the ability to chroot... but the capabilities aren't well understood in the real world. Playing with them too much will break things in new and interesting ways... I'm not sure if I'd trust them to work as they should, and they'd interfere with being able to chroot things in the virtual environment (which you may want to do). Oh, yeah, and the above behavior of chroot() isn't really a bug in Linux: it's a bug in POSIX. (I'm not willing to say that jail() is a panacea either... it's been abused on FreeBSD -- see http://www.securityfocus.com/archive/1/153336 for example.) -- CueCat decoder .signature by Larry Wall: #!/usr/bin/perl -n printf "Serial: %s Type: %s Code: %s\n", map { tr/a-zA-Z0-9+-/ -_/; $_ = unpack 'u', chr(32 + length()*3/4) . $_; s/\0+$//; $_ ^= "C" x length; } /\.([^.]+)/g;