User chroot
Subsystems (4)
PATCH 1/1 User chroot
Hi,
Have you ever wondered why normal users are not allowed to chroot?
I have. The reasons I can figure out are:
* Changing root makes it trivial to trick suid/sgid binaries to do nasty things.
* If root calls chroot and changes uid, he expects that the process can not escape to the old root by calling chroot again.
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Example:
user:~$ /usr/sbin/traceroute 127.1 traceroute to 127.1 (127.0.0.1), 30 hops max, 38 byte packets 1 localhost (127.0.0.1) 6.658 ms 0.764 ms 0.613 ms user:~$ /usr/sbin/chroot / user:/$ /usr/sbin/traceroute 127.1 traceroute: icmp socket: Operation not permitted user:/$ /usr/sbin/chroot / /usr/sbin/chroot: cannot change root directory to /: Operation not permitted user:/$
Is there any reason why this could not be the default behavior for the official kernel?
Jörgen
CREDITS +7 -0
@@ -497,6 +497,13 @@ S: Fremont, California 94539 S: USA +N: Jörgen Cederlöf +E: [email protected] +D: User capabilities, user chroot +S: Rydsvägen 258 A.36 +S: 584 34 Linköping +S: Sweden + N: Gordon Chaffee E: [email protected] W: http://bmrc.berkeley.edu/people/chaffee/
fs/exec.c +5 -4
@@ -617,7 +617,7 @@if (!IS_NOSUID (inode)) {/* Set-uid? */ -if (mode &S_ISUID ) +if (mode &S_ISUID &&capable (CAP_EXECSUID )) bprm->e_uid = inode->i_uid;/* Set-gid? */
@@ -626,14 +626,15 @@* is a candidate for mandatory locking, not a setgid * executable. */ -if ((mode & (S_ISGID |S_IXGRP )) == (S_ISGID |S_IXGRP )) +if ((mode & (S_ISGID |S_IXGRP )) == (S_ISGID |S_IXGRP ) + &&capable (CAP_EXECSGID )) bprm->e_gid = inode->i_gid; }/* We don't have VFS support for capabilities yet */ -cap_clear (bprm->cap_inheritable); +cap_clear_set_user (bprm->cap_inheritable);cap_clear (bprm->cap_permitted); -cap_clear (bprm->cap_effective); +cap_clear_set_user (bprm->cap_effective);/* To support inheritance of root-permissions and suid-root * executables under compatibility mode, we raise all three
fs/open.c +14 -1
@@ -421,9 +421,22 @@ goto dput_and_out; error = -EPERM ; -if (!capable (CAP_SYS_CHROOT )) +if (!capable (CAP_SYS_CHROOT ) && !capable (CAP_USER_CHROOT )) goto dput_and_out; +if (!capable (CAP_SYS_CHROOT )) { +cap_lower (current->cap_effective,CAP_EXECSUID ); +cap_lower (current->cap_permitted,CAP_EXECSUID ); +cap_lower (current->cap_inheritable,CAP_EXECSUID ); +cap_lower (current->cap_effective,CAP_EXECSGID ); +cap_lower (current->cap_permitted,CAP_EXECSGID ); +cap_lower (current->cap_inheritable,CAP_EXECSGID ); + } + +cap_lower (current->cap_effective,CAP_USER_CHROOT ); +cap_lower (current->cap_permitted,CAP_USER_CHROOT ); +cap_lower (current->cap_inheritable,CAP_USER_CHROOT ); +set_fs_root (current->fs, nd.mnt, nd.dentry);set_fs_altroot (); error =0 ;
include/linux/capability.h +37 -6
69 lines not on this page · raw message
include/linux/sched.h +2 -1
@@ -701,7 +701,8 @@ if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)#endif { - current->flags |=PF_SUPERPRIV ; +if (!(CAP_TO_MASK (cap) &CAP_USER_MASK )) + current->flags |=PF_SUPERPRIV ;return 1 ; }return 0 ;
Followup to: <20010627014534.B2654@ondska> By author: Jorgen Cederlof <[email protected]> In newsgroup: linux.dev.kernel
Quoted 8 lines
Have you ever wondered why normal users are not allowed to chroot?
I have. The reasons I can figure out are:
* Changing root makes it trivial to trick suid/sgid binaries to do nasty things.
Quoted 7 lines
* If root calls chroot and changes uid, he expects that the process can not escape to the old root by calling chroot again.
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Safe, perhaps, but also completely useless: there is no way the user can set up a functional environment inside the chroot. In other words, it's all pain, no gain.
-hpa
Signature · 3 lines
<[email protected]> at work, <[email protected]> in private! "Unix gives you enough rope to shoot yourself in the foot." http://www.zytor.com/~hpa/puzzle.txt
Quoted 12 lines · H. Peter Anvin
[somebody]
Quoted 10 lines
Have you ever wondered why normal users are not allowed to chroot?
I have. The reasons I can figure out are:
* Changing root makes it trivial to trick suid/sgid binaries to do nasty things.
* If root calls chroot and changes uid, he expects that the process can not escape to the old root by calling chroot again.
Quoted 7 lines
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Safe, perhaps, but also completely useless: there is no way the user can set up a functional environment inside the chroot. In other words, it's all pain, no gain.
Normal users can use an environment provided for them.
While trying to figure out why the "heyu" program would not work on a Red Hat box, I did just this. As root I set up all the device files needed, along Debian libraries and the heyu executable itself. It was annoying that I couldn't try out my chroot environment as a regular user.
Creating the device files isn't a big deal. It wouldn't be hard to write a setuid app to make the few needed devices. If we had per-user limits, "mount --bind /dev/zero /foo/zero" could be allowed. One way or another, devices can be provided.
Quoted 9 lines · Albert D. Cahalan
Normal users can use an environment provided for them.
While trying to figure out why the "heyu" program would not work on a Red Hat box, I did just this. As root I set up all the device files needed, along Debian libraries and the heyu executable itself. It was annoying that I couldn't try out my chroot environment as a regular user.
Quoted 5 lines
Creating the device files isn't a big deal. It wouldn't be hard to write a setuid app to make the few needed devices. If we had per-user limits, "mount --bind
/dev/zero/foo/zero" could be allowed. One way or another, devices can be provided.
Hell no! This would give the user a way to subvert root or other system-provided things by having device nodes or such appear where they aren't expected. NOT GOOD.
-hpa
[email protected] (H. Peter Anvin) wrote on 26.06.01 in <[email protected]>:
Quoted 18 lines
Quoted 9 lines · Albert D. Cahalan
Normal users can use an environment provided for them.
While trying to figure out why the "heyu" program would not work on a Red Hat box, I did just this. As root I set up all the device files needed, along Debian libraries and the heyu executable itself. It was annoying that I couldn't try out my chroot environment as a regular user.
Quoted 5 lines
Creating the device files isn't a big deal. It wouldn't be hard to write a setuid app to make the few needed devices. If we had per-user limits, "mount --bind
/dev/zero/foo/zero" could be allowed. One way or another, devices can be provided.
Quoted 3 lines
Hell no! This would give the user a way to subvert root or other system-provided things by having device nodes or such appear where they aren't expected. NOT GOOD.
Well, only allow them where you expect them then. That's easy enough.
MfG Kai
Quoted 10 lines · H. Peter Anvin
Quoted 8 lines · Albert D. Cahalan
Normal users can use an environment provided for them.
While trying to figure out why the "heyu" program would not work on a Red Hat box, I did just this. As root I set up all the device files needed, along Debian libraries and the heyu executable itself. It was annoying that I couldn't try out my chroot environment as a regular user.
Quoted 8 lines
Quoted 4 lines
Creating the device files isn't a big deal. It wouldn't be hard to write a setuid app to make the few needed devices. If we had per-user limits, "mount --bind
/dev/zero/foo/zero" could be allowed. One way or another, devices can be provided.Hell no! This would give the user a way to subvert root or other system-provided things by having device nodes or such appear where they aren't expected. NOT GOOD.
On every normal (default Red Hat or Debian at least) system this is already trivial:
ln /dev/zero /tmp/zero
ln /dev/hda ~/hda
ln /dev/mem /var/tmp/README
So the user often can provide device nodes. The above is _worse_ than allowing "mount --bind ..." because the admin has to search the whole filesystem to find such links.
Never mind that though; it doesn't matter how the devices are created. Social engineering can work. Once the device problem is taken care of, chroot() becomes useful for normal users.
BTW, it is way wrong that /dev/zero should be needed at all. Such use is undocumented ("man zero", "man mmap") anyway, and AFAIK one should use mmap() with MAP_ANON instead. Not that the documentation on MAP_ANON is any good either, but at least the mere existence of the flag is mentioned.
Quoted 7 lines · Albert D. Cahalan
BTW, it is way wrong that
/dev/zeroshould be needed at all. Such use is undocumented ("man zero", "man mmap") anyway, and AFAIK one should usemmap()withMAP_ANONinstead. Not that the documentation onMAP_ANONis any good either, but at least the mere existence of the flag is mentioned.
RTFM(POSIX).
-hpa
Quoted 9 lines · H. Peter Anvin
Quoted 5 lines · Albert D. Cahalan
BTW, it is way wrong that
/dev/zeroshould be needed at all. Such use is undocumented ("man zero", "man mmap") anyway, and AFAIK one should usemmap()withMAP_ANONinstead. Not that the documentation onMAP_ANONis any good either, but at least the mere existence of the flag is mentioned.RTFM(POSIX).
No manual entry for RTFM in section POSIX
Seriously:
1. both features ought to be documented in the man pages (I did submit a man page too, back in 1996)
2. it is slow and nasty to open /dev/zero for getting memory
Quoted 3 lines · Albert D. Cahalan
ln
/dev/zero/tmp/zero
ln/dev/hda~/hda
ln/dev/mem/var/tmp/README
None of these (of course) work if you use mount options to restrict device nodes on those filesystems.
Sean
Quoted 8 lines · Sean Hunter
Quoted 3 lines · Albert D. Cahalan
ln
/dev/zero/tmp/zero
ln/dev/hda~/hda
ln/dev/mem/var/tmp/READMENone of these (of course) work if you use mount options to restrict device nodes on those filesystems.
In which case, you can't boot. Think about it.
Never mind the method. One way or another, it is very often possible for a normal users to set up a chroot environment with the device files that are needed. Maybe they do something obscene with the admin. :-) So chroot() is useful for users.
In my case, I _am_ the admin and I just don't want to run every damn little test program and hack as root.
Quoted 9 lines · [email protected] ("H. Peter Anvin") writes:
Followup to: <20010627014534.B2654@ondska> By author: Jorgen Cederlof <[email protected]> In newsgroup: linux.dev.kernelQuoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Safe, perhaps, but also completely useless: there is no way the user can set up a functional environment inside the chroot.
Why? Because he can't create device nodes?
First of all, if /dev is on the same file system as the new root, the user can ln the device nodes he wants to wherever he wants them in the new root. He can't change their permissions, but that should not be necessary.
Since I use devfs, I can't do that. But I decided to try how much I can do anyway. So I downloaded the big redhat 7.1 image from User-mode Linux. I unpacked it and extracted it to a directory using User-mode Linux. Since I was a normal user, I could not create any device nodes so I left /dev empty.
I chrooted into the directory. Most things seemed to work. I couldn't use ping, since it needs to be suid root, and ps didn't work for obvious reasons, but besides that everything looked OK.
I started an Xnest and started a gnome-session in it. Now I ran into trouble. Some programs complained that they could not open /dev/null. I touched /dev/null and put a couple of zeroes in /dev/zero just in case. Now everything worked just fine. Gnome started and I could run every application included.
The only thing that didn't work was terminal emulators. If I had not been using devfs, but had /dev on the same file system as /tmp or ~, I could have linked the needed device nodes. If you want to, you can have a daemon running outside the root to mirror selected parts of /proc into new_root/proc.
There are more uses for chroot than running user desktops, as has been pointed out by others. The same arguments as implementing chroot for root still applies.
Securing network daemons without needing to be root can be useful. As an extra bonus, cracked daemons are prevented from gaining root access from buggy suid binaries.
I'm sure you can think of more uses. Don't assume it has no uses just because you can't think of anything in two minutes. I tend to use it quite often now when I am used to it, and I often find it frustrating to work on computers without this patch.
Jörgen
Quoted 7 lines · H. Peter Anvin
By author: Jorgen Cederlof <[email protected]>
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Safe, perhaps, but also completely useless: there is no way the user can set up a functional environment inside the chroot.
Why is it useless? It sounds useful to me, on first glance. If I want to run a user-level network daemon I don't trust (for instance, fingerd), isolating it in a chroot area sounds pretty nice: If there is a buffer overrun in the daemon, you can get some protection [*] against the rest of your system being trashed. Am I missing something obvious?
[*] Yes, I know chroot is not sufficient on its own to completely
protect against this, but it is a useful part of the puzzle, and there are other things we can do to deal with the remaining holes.
Quoted 6 lines · David Wagner
Quoted 5 lines · H. Peter Anvin
By author: Jorgen Cederlof <[email protected]>
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Quoted 8 lines
Quoted 2 lines
Safe, perhaps, but also completely useless: there is no way the user can set up a functional environment inside the chroot.
Why is it useless? It sounds useful to me, on first glance. If I want to run a user-level network daemon I don't trust (for instance, fingerd), isolating it in a chroot area sounds pretty nice: If there is a buffer overrun in the daemon, you can get some protection [*] against the rest of your system being trashed. Am I missing something obvious?
Just write a small program that chroots, drop privileges, and execs the untrusted daemon.
.TM.
Signature · 5 lines
____/ ____/ /
/ / / Marco Colombo
___/ ___ / / Technical Manager
/ / / ESI s.r.l.
_____/ _____/ _/ [email protected]Quoted 7 lines · David Wagner
Why is it useless? It sounds useful to me, on first glance. If I want to run a user-level network daemon I don't trust (for instance, fingerd), isolating it in a chroot area sounds pretty nice: If there is a buffer overrun in the daemon, you can get some protection [*] against the rest of your system being trashed. Am I missing something obvious?
if you don't mind running fingerd on a non-privleged (>1024) port.
-Tony
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
Anthony J. Biacco Network Administrator/Engineer
[email protected] Intergrafix Internet Services
"Dream as if you'll live forever, live as if you'll die today"
http://www.asteroid-b612.org http://www.intergrafix.net
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
[email protected] (Jorgen Cederlof) wrote on 27.06.01 in <20010627014534.B2654@ondska>:
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Hmm. Dos this work with initrd and root pivoting?
MfG Kai
Quoted 9 lines · [email protected] ("H. Peter Anvin") writes:
Followup to: <20010627014534.B2654@ondska> By author: Jorgen Cederlof <[email protected]> In newsgroup: linux.dev.kernelQuoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Safe, perhaps, but also completely useless: there is no way the user can set up a functional environment inside the chroot.
Huh? Why wouldn't you be able to set up a functional environment? I can think of quite a lot of things you can do without device nodes or /proc ...
Or are you referring to something else?
//Marcus
Signature · 4 lines
---------------------------------+---------------------------------
Marcus Sundberg | Phone: +46 707 452062
Embedded Systems Consultant | Email: [email protected]
Cendio Systems AB | http://www.cendio.comFollowup to: <[email protected]> By author: [email protected] (Kai Henningsen) In newsgroup: linux.dev.kernel
Quoted 9 lines
[email protected] (Jorgen Cederlof) wrote on 27.06.01 in <20010627014534.B2654@ondska>:
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Hmm. Dos this work with initrd and root pivoting?
At the moment, yes. Once Viro gets his root-changes in, this breaks, since ALL processes will be chrooted.
-hpa
Signature · 3 lines
<[email protected]> at work, <[email protected]> in private! "Unix gives you enough rope to shoot yourself in the foot." http://www.zytor.com/~hpa/puzzle.txt
[email protected] (H. Peter Anvin) wrote on 27.06.01 in <[email protected]>:
Quoted 9 lines
By author: [email protected] (Kai Henningsen)
Quoted 7 lines
[email protected] (Jorgen Cederlof) wrote on 27.06.01 in <20010627014534.B2654@ondska>:
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Quoted 5 lines
Quoted 2 lines
Hmm. Dos this work with initrd and root pivoting?
At the moment, yes. Once Viro gets his root-changes in, this breaks, since ALL processes will be chrooted.
About what I expected. So you'd really want this flag to be resettable by root, if you go that way at all. Beginning to look a little too compley, I think.
The last time, ISTR we discussed some other, similar-but-different syscalls that made for more secure jails. I don't quite remember the details, though.
MfG Kai
Quoted 8 lines · H. Peter Anvin
Quoted 5 lines
Quoted 3 lines
If we only allow user chroots for processes that have never been chrooted before, and if the suid/sgid bits won't have any effect under the new root, it should be perfectly safe to allow any user to chroot.
Hmm. Dos this work with initrd and root pivoting?
At the moment, yes. Once Viro gets his root-changes in, this breaks, since ALL processes will be chrooted.
What are those changes, and how will they break user chroots?
Jörgen