"If you have the ability to use chroot() you are root. If you are root you can walk happily out of any chroot by a thousand other means," Alan Cox explained during a thread that suggested chroot was broken in Linux. It was further pointed out that this was true per the POSIX specification, and per other OS's implementations. Al Viro suggested this should be added to the lkml FAQ, explaining:
"If you are within chroot jail and capable of chroot(), you can chdir to its root, then chroot() to subdirectory and you've got cwd outside of your new root. After that you can chdir all way out to original root. Again, this is standard behaviour. Changing it will not yield any security improvements, so kindly give that a rest."
When it was suggested that chroot is frequently used as a security tool, Adrian Bunk retorted, "incompetent people implementing security solutions are a real problem." Alan added, "chroot is not and never has been a security tool. People have built things based upon the properties of chroot but extended (BSD jails, Linux vserver) but they are quite different."
From: Alan Cox Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 19, 2:40 am 2007 On Wed, 19 Sep 2007 09:19:50 +0200 majkls <majkls@prepere.com> wrote: > Hello, > here is an fix to an exploit (obtained somewhere in internet). This > exploit can workaround chroot with CAP_SYS_CHROOT. It is also possible > (with sufficient filedescriptor (if there is na directory fd opened in > root) workaround chroot with sys_fchdir. This patch fixes it. If you have the ability to use chroot() you are root. If you are root you can walk happily out of any chroot by a thousand other means. Alan -
From: Bill Davidsen Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 19, 11:27 am 2007 Alan Cox wrote: > On Wed, 19 Sep 2007 09:19:50 +0200 > majkls <majkls@prepere.com> wrote: > >> Hello, >> here is an fix to an exploit (obtained somewhere in internet). This >> exploit can workaround chroot with CAP_SYS_CHROOT. It is also possible >> (with sufficient filedescriptor (if there is na directory fd opened in >> root) workaround chroot with sys_fchdir. This patch fixes it. > > > If you have the ability to use chroot() you are root. If you are root you > can walk happily out of any chroot by a thousand other means. > I thought this was to prevent breaking out of chroot as a normal user. ie. chroot /var/myjail /bin/su - guest or similar. -- Bill Davidsen <davidsen@tmr.com> "We have more to fear from the bungling of the incompetent than from the machinations of the wicked." - from Slashdot -
From: Alan Cox Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 19, 11:45 am 2007 > I thought this was to prevent breaking out of chroot as a normal user. > ie. chroot /var/myjail /bin/su - guest > or similar. Normal users cannot use chroot() themselves so they can't use chroot to get back out -
From: David Newall Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 19, 3:24 pm 2007 > Normal users cannot use chroot() themselves so they can't use chroot to > get back out I think Bill is right, that this is to fix a method that non-root processes can use to escape their chroot. The exploit, which is documented in chroot(2)*, is to chdir("..") your way out. Who'd have thought it? Only root can do that, but even that seems wrong. Chroot should be chroot and that should be the end of it. It looks to me like Miloslav has found a bug, although I suspect there's a simpler solution because non-root is already prevented from escaping this way. David * In particular, the superuser can escape from a ‘chroot jail’ by doing ‘mkdir foo; chroot foo; cd ..’. -
From: Phillip Susi Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 21, 10:39 am 2007 David Newall wrote: > * In particular, the superuser can escape from a =91chroot jail=92 by d= > oing=20 > =91mkdir foo; chroot foo; cd ..=92. No, he can not. -
From: Alan Cox Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 21, 11:10 am 2007 On Fri, 21 Sep 2007 13:39:34 -0400 Phillip Susi <psusi@cfl.rr.com> wrote: > David Newall wrote: > > * In particular, the superuser can escape from a =91chroot jail=92 by d= > > oing=20 > > =91mkdir foo; chroot foo; cd ..=92. > > No, he can not. The superuser can escape that way - its expected and fine behaviour -
From: Phillip Susi Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 25, 1:53 pm 2007 Alan Cox wrote: > On Fri, 21 Sep 2007 13:39:34 -0400 > Phillip Susi <psusi@cfl.rr.com> wrote: > >> David Newall wrote: >>> * In particular, the superuser can escape from a =91chroot jail=92 by d= >>> oing=20 >>> =91mkdir foo; chroot foo; cd ..=92. >> No, he can not. > > The superuser can escape that way - its expected and fine behaviour Does not work for me, and that would be the EXACT thing chroot is supposed to prevent. Maybe you guys are thinking of a program that calls chroot() but leaves cwd outside the chroot still being able to navigate outside of it? -
From: Al Viro Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 25, 5:23 pm 2007 On Tue, Sep 25, 2007 at 04:53:00PM -0400, Phillip Susi wrote: > Alan Cox wrote: > >On Fri, 21 Sep 2007 13:39:34 -0400 > >Phillip Susi <psusi@cfl.rr.com> wrote: > > > >>David Newall wrote: > >>>* In particular, the superuser can escape from a =91chroot jail=92 by d= > >>>oing=20 > >>>=91mkdir foo; chroot foo; cd ..=92. > >>No, he can not. > > > >The superuser can escape that way - its expected and fine behaviour > > Does not work for me, and that would be the EXACT thing chroot is > supposed to prevent. Maybe you guys are thinking of a program that > calls chroot() but leaves cwd outside the chroot still being able to > navigate outside of it? Oh, for fsck sake... Folks, it's standard-required behaviour. Ability to chroot() implies the ability to break out of it. Could we please add that (along with reference to SuS) to l-k FAQ and be done with that nonsense? If you are within chroot jail and capable of chroot(), you can chdir to its root, then chroot() to subdirectory and you've got cwd outside of your new root. After that you can chdir all way out to original root. Again, this is standard behaviour. Changing it will not yield any security improvements, so kindly give that a rest. -
From: David Newall Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 26, 3:34 am 2007 Al Viro wrote: > Oh, for fsck sake... Folks, it's standard-required behaviour. Ability > to chroot() implies the ability to break out of it. Could we please > add that (along with reference to SuS) to l-k FAQ and be done with that > nonsense? I'm pretty confident that it's only standard behavior for Linux. Every other unix says it's not allowed. -
From: Alan Cox Subject: Re: sys_chroot+sys_fchdir Fix Date: Sep 26, 4:21 am 2007 On Wed, 26 Sep 2007 20:04:14 +0930 David Newall <david@davidnewall.com> wrote: > Al Viro wrote: > > Oh, for fsck sake... Folks, it's standard-required behaviour. Ability > > to chroot() implies the ability to break out of it. Could we please > > add that (along with reference to SuS) to l-k FAQ and be done with that > > nonsense? > > I'm pretty confident that it's only standard behavior for Linux. Every > other unix says it's not allowed. Go try them, then come back and admit your error -
From: Alan Cox Subject: Re: Chroot bug Date: Sep 25, 8:48 am 2007 On Wed, 26 Sep 2007 01:05:07 +0930 David Newall <david@davidnewall.com> wrote: > Alan Cox wrote: > >> Marek's loading dynamic libraries, it seems clear that the prime purpose > >> of chroot is to aid security. Being able to cd your way out is handy > >> > > > > Does it - I can't find any evidence for that. > > It seems self-evident to me. What do you think is it prime purpose? Debugging and testing. At least that is as I understand it much of where it came from. > > A root user can get out of a chroot a million different ways > One of those ways shouldn't be that chroot lets you out. A fence with 10000 open gates is not improved by turning it into a fence with 9999 open gates. -
From: David Newall Subject: Re: Chroot bug Date: Sep 25, 4:50 pm 2007 Alan Cox wrote: > On Wed, 26 Sep 2007 01:05:07 +0930 > David Newall <david@davidnewall.com> wrote: >> Alan Cox wrote: >> >>>> Marek's loading dynamic libraries, it seems clear that the prime purpose >>>> of chroot is to aid security. Being able to cd your way out is handy >>>> >>>> >>> Does it - I can't find any evidence for that. >>> >> It seems self-evident to me. What do you think is it prime purpose? >> > > Debugging and testing. At least that is as I understand it much of where > it came from. > Good call. Though I suppose, since it's used 24x7 to aid security on countless production servers, that security dwarfs testing. Still, debugging, yes that's valid. I don't suppose it makes and difference; whatever the purpose, a chroot that doesn't change the root is buggy. -
From: Alan Cox Subject: Re: Chroot bug Date: Sep 25, 5:18 pm 2007 > Good call. Though I suppose, since it's used 24x7 to aid security on > countless production servers, that security dwarfs testing. Still, > debugging, yes that's valid. > > I don't suppose it makes and difference; whatever the purpose, a chroot > that doesn't change the root is buggy. It does change the root, it just doesn't guarantee you can't change it back - which is correct POSIX, Unix, SuS behaviour. So either everyone else is wrong or you are.. I know who I am betting on -
From: David Newall Subject: Re: Chroot bug Date: Sep 26, 3:24 am 2007 Alan Cox wrote: >> Good call. Though I suppose, since it's used 24x7 to aid security on >> countless production servers, that security dwarfs testing. Still, >> debugging, yes that's valid. >> >> I don't suppose it makes and difference; whatever the purpose, a chroot >> that doesn't change the root is buggy. >> > > It does change the root, it just doesn't guarantee you can't change it > back - which is correct POSIX, Unix, SuS behaviour. So either everyone > else is wrong or you are.. I know who I am betting on > Charming. They really say that, do they? Where? I find no such thing, and I looked. I did find Open Groups SuS which, similar to SCO's UNIX, says: > The dot-dot entry in the root directory is interpreted to mean the > root directory itself. Thus, dot-dot cannot be used to access files > outside the subtree rooted at the root directory. I feel I've presented a good case that that it's a bug. You made a somewhat rude counter-claim, which I don't ascribe to malevolence. You're simply disinterested. Nobody else cares, so why expend effort on it, right? I'll let it drop, but it is a bug. -
From: Alan Cox Subject: Re: Chroot bug Date: Sep 26, 3:47 am 2007 > > The dot-dot entry in the root directory is interpreted to mean the > > root directory itself. Thus, dot-dot cannot be used to access files > > outside the subtree rooted at the root directory. Which is behaviour chroot preserves properly. The specification says explicitly "The process working directory is unaffected by chroot()." chroot is not and never has been a security tool. People have built things based upon the properties of chroot but extended (BSD jails, Linux vserver) but they are quite different. You could probably write yourself an LSM module to do this too Alan -


Inconsistency?
It seems to me the real problem here is one of consistency. If I'm reading the thread right, it seems:
".." means different things to different users (root vs a normal user)
and/or
".." means different things in different contexts (chroot() vs chdir)
Neither of these seem desireable conflicts: shouldn't ".." always mean the same thing to everybody?
Of course, I still wonder why non-root users shouldn't be able to chroot() into whatever subset of
directories they already have access to.. Making this privledged seems indicative of a more serious
design flaw regarding how permissions are handled. Shouldn't /anybody/ be able to do /anything/ they
want with things they already have access to?
My first guess is "chroot() would make programs see a different /etc/passwd", but it sounds wrong,
as "su" would still require root privledges to begin with (and a different "su" would also be
required..)
What is the reasoning?
{I am aware that many interpret my style of writing as "hostile", please read it instead as
"inquisitive to an annoying extent". I do tend to ask questions and, apon receiving an answer,
challenge that answer until it covers various related thoughts on the matter. I consider this
"conversation", not "attack", and always come into a conversation with the assumption that my
beliefs that something seems "wrong" are due to my ignorance of various aspects of the problem.
Ignorance which I seek to alleviate by asking questions. Can you guess whether or not I've
tried to ask this question before? :D}
If unpriviledged user could
If unpriviledged user could do chroot(2), she could do something like this:
mkdir -p my_root/lib
cp /lib/* my_root/lib
cp my_evil_libc_replacement/libc.so my_root/lib
ln /bin/passwd my_root/passwd
chroot my_root passwd
Et voila, your own library loaded into suid process.
Doesn't that follow the same issue, though?
Why should it matter what fake libc they have in their chrooted environment, though? They still can't do any damage without root access, which they're not going to get unless root personally copied some setuid'd programs into their chrooted environment (or is this not the case?).
In summary: wouldn't that being an issue already imply some sort of privledge escalation has taken place?
Breaking out
One might be able to do timing attacks or similar maybe?
possible nm, I seem to understand now..
I was not aware that regular users could create links to files they don't have full access to.
(unrelated: why is this the case? Other than "no reason not to".. or is that all? I don't use non-symbolic links a lot..)
Appologies for having not tested the last line of your previous post for myself
you can create symbolic links
... but you still can't access the files. The only real gain are symlink attacks in e.g. the /tmp directory for programs with suid root.
Hard links
You can create hard links to files if you have execute access on the directory containing them and you know the filename. You don't need to have any rights to the file itself. You only need to be able to stat() it.
Hard links work by associating a new directory entry with an existing inode. Inodes contain the ownership and permission information associated with a file. Directory entries associate names with inodes, and hard links are just additional such associations. This is also why hard links don't generally cross filesystem boundaries.
Because of this property, if you have a writable directory in the same filesystem as the normal runtime environment (/etc, /lib, /bin, /usr), you can hard link as much as you want into a chroot arena ahead of time without using any meaningful amount of disk space. This is convenient if you're using chroot to present a limited view of the system to a program. If you want to attack a program by confusing it and/or misdirecting it, you can provide a mostly-normal view to it and change just a few details. This goes to why it's bad to let mortal users chroot.
I do take issue with the idea that chroot is not useful for security. If you have a service that runs as a mortal user, chroot can be useful for containing that process somewhat, and hiding from it information it doesn't need to do its job. It's NOT useful for containing root, though, and so it has limited security usefulness. Saying chroot isn't useful for security is like saying chmod isn't useful for security. :-)
--
Program Intellivision and play Space Patrol!
AFAIK it's for historical
AFAIK it's for historical reasons. On some systems you can disable that behaviour, i.e. deny users from hardlinking to files they don't own.
It's only logical that users
It's only logical that users can only link to files they have access to. What systems are you talking about.
On typical unix-like -
On typical unix-like - Linux, Solaris, BSD, whatever; AFAIK it's mandated by POSIX - user can create hardlink to any file of which she can get inode number, i.e. to any file she can see with 'ls', i.e. to any file which containing directory contents she can read. It's _not_ neccessary to be able to access the file itself, one _may_ hardlink to the file she cannot open. Note, however, that in that case she won't be able to open the link anyway; permissions and owner fields (and the rest of inode) are shared between the 'original' file and the hardlink.
This behaviour is stupid IMHO, but is mandated by the standard, so it remains the default. On Linux with grsecurity, or in stock FreeBSD (no idea about other systems), administrator may change that. On FreeBSD, just set "security.bsd.hardlink_check_uid=1".
Suid executables don't use
Suid executables don't use dynamic libraries.
Says who? # ls -l
Says who?
# ls -l /usr/bin/passwd -rws--x--x 1 root root 36092 2007-06-19 00:59 /usr/bin/passwd # file /usr/bin/passwd /usr/bin/passwd: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped # ldd /usr/bin/passwd linux-gate.so.1 => (0xb7eee000) libcrypt.so.1 => /lib/libcrypt.so.1 (0xb7eaa000) libc.so.6 => /lib/libc.so.6 (0xb7d68000) /lib/ld-linux.so.2 (0xb7eef000)LD_PRELOAD
The person you're replying to may have been confused. SUID/SGID executables ignore LD_PRELOAD. (Well, not 100% exactly true, but pretty close. Read the ld.so man page for all the special restrictions placed on dynamic linking w/ SUID/SGID executables.)
--
Program Intellivision and play Space Patrol!
Here's how I understand it
If your cwd is inside the chroot() space, if you chdir(".."), you'll keep going up the tree, but will be stopped once you reach the top of the chroot(). The reason you're stopped is that your cwd is the root of the chroot(), and that's the special case the chroot() code looks for to prevent you from going up the tree.
If you're superuser, though, you can run chroot() from within a chroot(). If you chroot() to a subdirectory, this changes the notion of "root of the chroot()." Your cwd is now above that root. If you try to chdir(".."), you can now go to the parent of the cwd. You can iteratively walk your way all the way up to the original root.
The punchline: If your cwd is in the chroot space, chdir() can't take you out of the chrooted space. If your cwd starts outside the chroot space, nothing forces you into the chroot space. Because chroots don't nest, root can escape chroot by chrooting to a subdirectory, thereby placing cwd outside the chroot.
As for not letting mortal users chroot()... If the mortal user has write access on any filesystem containing system binaries and files, they can hard-link to those binaries and files inside the chroot "jail" ahead of time. They can then put other files of their own creation in choice places (e.g. replace libc as someone suggested, or change other configuration files) and run SUID programs that are "too trusting" (e.g. programs that don't check for UID or GID=0 on libraries or config files) and get them to misbehave.
Note that such an attack is much more difficult (impossible?) if mortal users do not have writable directories on the same filesystem as system libraries, executables and configuration scripts. Hard links generally do not cross filesystem boundaries.
--
Program Intellivision and play Space Patrol!
Yes but
I'm not sure there's a "generally" about it. They point to inodes, and therefor the file and the hard link both have to be on the same device.
different meanings of ".."
The problem is that you're seeing small things in a discussion without having the background information.
".." always means the same thing. Chroot works like this:
1. Create or mount a new rootdir somewhere inside your current one
2. make that your new root dir using 'chroot'
Say the old structure is:
/blah
/blah/chrootdir
Now you do:
chroot /blah/chrootdir /bin/bash
You are now in a bash shell in /blah/chrootdir - except that on the virtual filesystem, /blah/chrootdir appears to be '/' and not '/blah/chrootdir'.
So, when you do a ".." from '/' you get the expected behavior - the directory does not appear to change. Buggy behavior would be to put you into the directory '/blah' when you do '..' from '/' inside chroot. This behavior is different from what is expected of symlinked directories, but in all cases ".." means the same thing - the parent directory. It's just that in the given case of chroot, '/blah/chrootdir' is its own parent - which is what we want. In fact if that wasn't the behavior, a million other things will break and I wouldn't be able to do my job.
I think you misunderstood me...
If I'm reading you right, you seem to be defending against the opposite of what I said.
The point wasn't "'..' means something different inside and outside of a chroot()'d environment", it was "'..' means something different to the chroot() call than it does to anything else"
That is: once you have chrooted, ".." on the "fake root" refers to itself - except in the chroot() call. I wasn't saying once you have chrooted ".." should still let you get back out with a "cd" command, I was saying that chroot() seems to ignore the new rules it sets up, and that seems inconsistent.
And now I wonder if anyone
And now I wonder if anyone is wondering why noone wants to suggest something to Kernel folks, if rude
initial responds such as Alan Cox's one are presented?
Because the original message was silly?
I heard methods for escaping from chroot() jails years and years and years ago. That someone is showing up now going "OMG EXPLOIT" is worthy of a "Hey, do your homework first." Reminds me of that ancient Dilbert strip...
That said, FreeBSD and other UNIXes apparently has extended chroot in ways that help, but still aren't a panacea. That's fine and all, but if you walk in expecting those extensions to be standard behavior on another OS, you should be prepared for disappointment rather than going around telling kernel hackers they're wrong.
--
Program Intellivision and play Space Patrol!
rude comments
I didn't see the comments as rude. The original poster was incorrect in believing there was a bug. It appears that the original poster didn't bother to read about 'chroot' and its expected behavior.
No offense, but if you
No offense, but if you didn't see Cox's remarks as rude then you're either ignorant or just defending him out of blind zealotry.
On high-volume lists or
On high-volume lists or forums you can't expect people to coddle the ignorant. If somebody on a tech list responds to your post and says in no uncertain terms that you're 100% wrong, then that person should stop and think before reacting. It's no defense to say that the response wasn't sufficiently detailed to sway the poster. The tone of the post in such cases is more important than some long-winded exposition; it's a hint that the OP is clueless.
You also have to think about archives. You don't want people coming across that post 2 years from now believing that the original post had merit because the responses were vague and soft (i.e. wish-washy).
Some of us are PDD...
Some of us are PDD...
No offense, but if you
No offense, but if you didn't see Cox's remarks as rude then you're either ignorant or just defending him out of blind zealotry.
Yes, you're so right! Everyone should be able to waste the kernel dev's time with poorly researched bullshit and get a polite response.
We wouldn't want to discourage people with poorly researched bullshit from wasting their time in future by being rude to them. And we certainly don't want them to stop arguing just because they're wrong.
The problem is that you think the Linux development process should be democratic for everyone instead of just those who know what they're talking about. This is a very common view amongst people who don't know what the fuck they're talking about, for obvious reasons.
Hear hear!
Good call Reeferlnc. Cox's remarks were rude [I would have said blunt, not rude, but whatever], but so what? I'd much rather see people fighting with vigor and vitriol *and being HONEST* with each other (emotionally and intellectually) than I would seeing them kill each other with kindness and politics. It's not about the personalities, it's about the code.
I think what anon's missing is that Alan is actually treating him like a peer, if not a friend. He's not pretending Dave et. al. is a 'customer', or a 'consumer' or a 'client' or some other nameless obstacle you bullshit to make go away; He's treating him like a PERSON who, at the moment, is talking out his arse. One of them will lose, and the other one will get a beer - and problem solved. Until next week's episode...
Also - I did *not* know that chroot was NOT implemented for security purposes, so I'd like to thank both Alan and Dave for fighting loudly enough to get my attention. ;)
Hint: You are being rude.
Hint: You are being rude. Yes, it is that easy to spot it!
Breaking out of a chroot
For understand better how we can break chroot() read this page: http://www.bpfh.net/simes/computing/chroot-break.html
Regards,
Luiz Vitor.
Thank goodness we can. There
Thank goodness we can.
There have been a few times were installing Linux or doing other such things I've needed to break out of chroot to fix something or other.
Only root can break out of a
Only root can break out of a chroot(). But the language is a misnomer, because chroot() was never meant to confine root in a security sense. Its like saying, "The warden can break out of a local prison". Well, I would hope so.
This may be apocryphal, but IIRC originally any user could use chroot(); it was a convenience interface. Only later were the semantics altered in *NIX so the kernel would only honor a chroot() call if the process' uid was 0. It was a small alteration to a simple system call which became useful to creating secure daemon applications in a very narrow sense.
Non-root users cannot break out of a chroot. The normal way to use chroot to lock down a network daemon is to use chroot + privilege separation. A simple example for a web server:
1) Start daemon as root.
2) bind() to port 80.
3) pw = getpwnam("luser"); assert(pw->pw_uid != 0). You can't do that after you chroot() because you shouldn't be able to see /etc/passwd.
4) chdir("/somewhere"). Also, be careful you have no open directory descriptors or other file descriptors the process shouldn't have while operating with reduced privileges. Think about where stdin, stdout and stderr are directed. Maybe you close all descriptors from 3 to getdtablesize(), excepting the ones you need (like the socket descriptor).
5) chroot("/somewhere") safe without any binaries, particularly no SUID binaries; ideally a file system that doesn't honor the SUID bit at all (often a /var partition if the sysadmin is diligent). You may need duplicates of things like /etc/resolv.conf, /dev/null, /dev/zero. (NOTE: If you're super paranoid you might want to chroot() to a filesystem that doesn't even allow device files.)
6) setuid(pw->pw_uid) (or setgid(pw->pw_gid); setuid(pw->pw_uid)).
7) accept() connections.
There are lots of other tricks to making sane *NIX process daemons, like how to fork, keeping/using parent watchdogs, syslog() v. stderr, advanced privsep techniques (i.e. descriptor passing), etc. There's no single way to do it in general; it needs to be narrowly tailored to the unique demands. However, there is only one way to use chroot() to lock down a process. In brief: chdir() + chroot() + setuid().
After ensuring all binaries,
After ensuring all binaries, libraries, etc in the chroot are not able to run suid root, one would imagine.
Don't forget to set seteuid!
Don't forget to set seteuid! Otherwise, your users will still effectively have root privileges.
Can't replicate the behavior described in the thread.
I found this topic pretty interesting in it's description of the expected behavior of chroot jails in linux. Unfortunately I've been unable to replicate the behavior described by David Newhall, namely:
mkdir foo;chroot foo;cd ..Aside from requiring a few files within the chroot (a shell for instance) I've been unable to jump up beyond the "root" defined by the chroot command. Am I missing something trivial in this discussion? I'm truly curious about this behavior and not 100% sure that I've understood the meat of the discussion.
TIA
-DFN
Something missing....
Yes, you are missing something -- and you aren't the only one to miss it. The folks who get it aren't missing it, but lots of other folks who are confused are.
The key is that there are two chroots under discussion. There's the system call chroot(2), and there is the administration command chroot(8). chroot(8) uses chroot(2) to do the key work, but other than that, it's not implicated in this "bug" at all.
The description of chroot(2) in its man page is particularly telling:
There are so many security issues mentioned in those few lines that its surprising that anyone might think chroot(2) is supposed to be for security.
Basically, chroot(2) changes the pathname resolution in this way (assuming that the current "root" directory is /chroot):
1) for absolute pathnames, interpret them as if they were prepended with /chroot. e.g. "/usr/bin" is treated as "/chroot/usr/bin"
2) for relative pathnames, interpret ".." in the "root" directory as pointing to the "root" directory.
This means that if an application made the following system calls:
chdir("/chroot"); chroot("/chroot"); FILE f = open("../etc/passwd");
then f would refer to /chroot/etc/passwd, since the .. from /chroot would be caught and made to refer to /chroot
However, if an application did the following:
chdir("/usr"); chroot("/chroot"); FILE f = open("../etc/passwd");
then f would refer to /etc/passwd, since the .. from /usr would not be redirected to /chroot.
The "bug" being highlighted here (which is incredibly old behavior, predating Linux by a long shot) is based on the idea that chroot(2) only muddles with pathname resolution and that a process only has a single chroot. This allows a process to use chroot(2) to "escape" if it knows what its doing.
So assuming that a process is being run "securely" chrooted to /chroot, the following sequence of calls will allow it to access /etc/passwd:
chdir("/"); mkdir("/foo"); chroot("/foo"); FILE f = open("../etc/passwd");
after the chdir("/") call, the current working directory would be /chroot. The mkdir() call creates /chroot/foo, and the chroot() call sets the current root to /chroot/foo, and the current working directory is still /chroot. The open() call tries to open /chroot/../etc/passwd using a relative path that does not pass through the current root /chroot/foo, so it doesn't get modified by the chroot call, and effectively accesses /etc/passwd without a problem.
In fact, except for the most pathological chroot jails the following system call sequence will reset chroot to the real root:
chdir("/"); mkdir("foo"); chroot("/foo"); chroot("../../../../../../../../../../../../../../../../../../../../../../..");
The question is: is this a bug, and if so, should it be fixed?
Alan's answer is simple: no, it's not a bug; it's how chroot(2) has worked historically in unices past, it's how it's documented to work, and chroot(2) was never intended to be secure. It's so full of security holes anyway patching this isn't worth it. Besides, it's only a problem if you can use chroot(2), which only root can do anyway. Once you've got a black-hat executing arbitrary code as root, keeping them from escaping a "chroot jail" is the least of your problems.
After all, a program running as root, even in a chroot jail, could just as easily mount a procfs or devfs within the chroot jail -- and access the contents without restriction. That's the keys to the kingdom.
chroot(8) is different. It doesn't allow the user to use chroot(2) in anything but a structured way, roughly equivalent to the first set of system calls I gave (the chdir("/chroot"); chroot("/chroot"); sequence), which ensures that you are properly "jailed". But if you can run your own program as root that can call chroot(2) directly, that program can "escape" without a problem.
"Alan's answer is simple:
chroot(8) is different. It doesn't allow the user to use chroot(2) in anything but a structured way"
That clears it up nicely. It sure is nice how certain other knowledgeable people let this discussion drag on and on, enjoying the fact that other people don't get this distinction. You're just ruining the nice fun gloating by letting the losers in on the joke.
Or, maybe you're just doing the right thing by educating people. Hard to tell the difference, isn't it? (Nah, not for me... but evidently it is for some people.)
Bad escape of chroot!!!
Solution:
---------
Imagine,
"pushroot directory" (equivalent to "chroot directory")
"poproot" (equivalent to escaping "cd .." only if the chrooted's stack is not empty).
The above example doesn't solution the security's problem because the PID can be the same but the program execve'd may be different e.g. trojan returned from chrooted environment.
The good solution is "Entering jail and exiting jail with exit(..)" or "permitting various chrooting but never escaping from it" (the root'ed trojan MUST to die before of EXITING from chrooted environment).
This is an alternative hidden escaping VERY DANGEROUS in chrooted environment:
"for X in $(seq 1 20) do mkdir -p /toescape$X ; mount /dev/hda$X /toescape$X ; chroot /toescape$X ; echo "HOHOHOHOHO OUT" ; done"
Don't use /dev/hda* and mount in an chrooted environment.
J.C. Pizarro.
Solution: Leveled Chroot and NEVER to escape to inferior level.
Master chroot from booting kernel is Level0 Chroot.
You can "chroot dir" from "level i" to "level i" or "level i+1", never in contrary direction.
The process can't escape from "level i chrooted environment" to "level i-1", and in this case, the process MUST TO die with exit(..) or signal KILL myself.
The process can escape from "level i chrooted environment" to same "level i".
Escaping chroot is DANGEROUS as SETUID, because, imagine the same shell, the same program, the same version, ... is TROJANED thanks to buffer overflow of the same shell who did enter to chrooted environment.
Before: running bash who did enter to chrooted environment.
After: same trojaned bash because of its vulnerability who "escapes" from chrooted environment.
J.C. Pizarro: "i'm the prisoner who escaped from the max-security jail".
they're right (there's a lot of other ways to get out of chroot)
For instance, if you have the mount capability you can simply mount /proc (some admins are nice enough to mount it for you!) and then cd /proc/1/cwd, you can still communicate via unix sockets, send signals, abuse shared memory, mknod the device in question and directly access it, take advantage of pre-existing open file descriptors in the process you owned, ptrace your way out, et cetera.
Really, chroot is a broken technology in regards to security, use jails/vserver/whatever else, but not chroot.
chroot is also broken if an
chroot is also broken if an admin creates you an empty password file and leaves a copy of "su" laying around. This example in particular doesn't imply that the unix authentication scheme is a broken technology.
Escaping chroot isn't a bug it's a feature
And it should be *easier* to escape chroot than it is now, as it's very useful when you're running software version N and you want to change into version N+1: you install the N+1 version on a partition and you use chroot so that the N+1 version believes it is alone.
But the issue is for migration: when you want to migrate some data from N to N+1, it is useful in the N+1 version to escape the chroot to access the N version and chroot makes it too difficult currently, I'd like to have a 'mount -echroot /mount_point' this way by default the N+1 version doesn't see the chroot and the migration scripts can work without problem.
When you rely on the old SW version mounting for the new version, there's always trouble..
just use mount
just use mount --bind
i.e:
mkdir /chroot2/olddata
mount --bind /chroot1/data /chroot2/olddata
chroot /chroot2 ...
And what happens if the old
And what happens if the old SW don't to do this on a partition needed by the new software?
Perfect hindsight is rare in the real world, you know..
chroot is a security tool
chroot is a security tool. It's just not a fool-proof security tool. If I run Apache in a chroot process, that means that a bug in Apache, or one of the installed modules, cannot accidentally expose other files. People can't go to http://mywebserver.com/../../../etc/passwd and see what's there (or more sophisticated versions through various scripts that may somehow allow people to inject filenames). It is not a security tool to prevent all breakins, however. If people can run arbitrary commands in a chroot jail, they've broken in. .
IIRC chroot was introduced
IIRC chroot was introduced in 4.3 or 4.2BSD as an aid in _building the system_. Compilation. Not a security feature of any kind. It can be used as a security thing, but it's not neccessarily a good idea. Jail, on the other hand, or the Solaris Zones - yeah, these were introduced as a security features.
I think that chroot can be
I think that chroot can be used as a security tool(?) but isn't designed for this purpose.
Defense in depth
Chroot (while not designed as a security tool) can provide an element in a DiD (Defense in Depth) strategy. It is certainly much less strong than many other elements you should have, and it is not appropriate in some cases. I am sure it would not be difficult to find examples of other technologies which were not designed with security in mind which are useful as an element in a DiD strategy.
Ultimately, security needs to be about a knowledgeable person putting in place a series of measures to make something hard to break into. Chroot may or may not be useful in any given circumstance, but certainly should never be RELIED upon by itself.
Always remember that there are times when ADDING a layer REDUCES security (double-pass XOR encryption anyone?). Somebody previously pointed out that if you don't need root for your process, adding chroot means you also need to add root access at some stage, which is dangerous.