[lxc-devel] A question about chroot_into_slave()

Serge Hallyn serge.hallyn at ubuntu.com
Thu Oct 2 21:57:02 UTC 2014


Hi Andrey,

The mailing list has been moved from sourceforge.net to linuxcontainers.org.
I'm replying here just to get the list involved.

-serge

Quoting Andrey Wagin (avagin at gmail.com):
> 2014-10-02 20:25 GMT+04:00 Serge Hallyn <serge.hallyn at ubuntu.com>:
> > Quoting Andrey Wagin (avagin at gmail.com):
> >> Hi All,
> >>
> >> chroot_into_slave() is called if the root / is ramfs.
> >>
> >> chroot_into_slave() mount tmpfs, creates a directory there and
> >> bind-mounts the host root into this directory.
> >> _ host_root
> >>  \_ tmp
> >>   \_ host_root (bind)
> >>    \_ ct_root
> >>
> >> Then pivot_root() exchange "host_root (bind)" and "ct_root" and
> >> "host_root (bind)". After that "host_root (bind)" is umounted.
> >> _host_root
> >>  \_ tmp
> >>    \_ct_root
> >>
> >> Here is my question. Why we can't do chroot(conf->rootfs.mount)
> >> instead of chroot_into_slave() & pivot_root(conf->rootfs.mount). I
> >> think the result will be the same with less amount of not obvious
> >> steps. Have I missed something?
> >
> > Do you mean not to pivot_root at all?  If so, because chroot is not
> > an adequate replacement:  you can trivially escape it, and /proc/mounts
> > wil be polluted.
> 
> /proc/ will not be polluted:
> 
> root at ubuntu:/home/avagin# chroot centos
> [root at ubuntu /]# mount -t proc proc /proc/
> [root at ubuntu /]# cat /proc/self/mountinfo
> 64 21 0:3 / /proc rw,relatime - proc proc rw
> 
> root at ubuntu:/home/avagin# cat /proc/9529/mountinfo
> 64 21 0:3 / /proc rw,relatime - proc proc rw
> 
> Now I want to show you, that chroot_into_slave() & pivot_root()
> doesn't defend you against escaping from a container. Let's repeate
> all actions, which lxc does for the root on ramfs. I don't have a host
> with root on ramfs, so I do all actions in my VM.
> 
> # chroot_into_slave()
> root at ubuntu:/home/avagin# unshare -m -- /bin/bash
> root at ubuntu:/home/avagin# mount --bind rootfs rootfs
> root at ubuntu:/home/avagin# mount --make-slave rootfs
> root at ubuntu:/home/avagin# mount -t tmpfs tmpfs rootfs
> root at ubuntu:/home/avagin# mkdir rootfs/root
> root at ubuntu:/home/avagin# mount --rbind / rootfs/root/
> root at ubuntu:/home/avagin# mount --make-rslave rootfs/
> root at ubuntu:/home/avagin# chroot rootfs/root/
> root at ubuntu:/# cd /
> 
> # mount_rootfs() & pivot_root()
> root at ubuntu:/# mount /home/avagin/centos /home/avagin/rootfs/
> mount: /home/avagin/centos is not a block device
> root at ubuntu:/# mount --bind /home/avagin/centos /home/avagin/rootfs/
> root at ubuntu:/# cd /home/avagin/rootfs/
> root at ubuntu:/home/avagin/rootfs# mkdir old
> root at ubuntu:/home/avagin/rootfs# pivot_root . old
> root at ubuntu:/home/avagin/rootfs# cd /
> root at ubuntu:/# cat /etc/redhat-release
> CentOS release 5.10 (Final)
> root at ubuntu:/# mount -t proc proc /proc/
> root at ubuntu:/# umount -l old/
> root at ubuntu:/# cat /proc/self/mountinfo
> 153 125 8:1 /home/avagin/centos / rw,relatime - ext4
> /dev/disk/by-uuid/291e7b1a-8396-44cf-9927-578b3401d0bd
> rw,errors=remount-ro,data=ordered
> 154 153 0:3 / /proc rw,relatime - proc proc rw
> 
> Now let's try to escape from this CT. I take the code from
> http://www.bpfh.net/simes/computing/chroot-break.html
> 
> root at ubuntu:/# ls -l /etc/redhat-release
> -rw-r--r-- 1 root root 28 Oct  7  2013 /etc/redhat-release
> root at ubuntu:/# ./breaking_chroot
> # ls -l /etc/redhat-release
> ls: cannot access /etc/redhat-release: No such file or directory
> #
> # cat /etc/lsb-release
> DISTRIB_ID=Ubuntu
> DISTRIB_RELEASE=14.04
> DISTRIB_CODENAME=trusty
> DISTRIB_DESCRIPTION="Ubuntu 14.04 LTS"
> 
> It works. We are able to escape from CT.
> 
> Now let's try to enter in CT's mount namespace:
> root at ubuntu:~# strace -e open,setns ./nsenter
> open("/proc/8580/ns/mnt", O_RDONLY)     = 3
> setns(3, 131072)                        = 0
> root at ubuntu:/# cat /proc/self/mountinfo
> 97 96 8:1 / / rw,relatime - ext4
> /dev/disk/by-uuid/291e7b1a-8396-44cf-9927-578b3401d0bd
> rw,errors=remount-ro,data=ordered
> ...
> 153 125 8:1 /home/avagin/centos /home/avagin/rootfs/root rw,relatime -
> ext4 /dev/disk/by-uuid/291e7b1a-8396-44cf-9927-578b3401d0bd
> rw,errors=remount-ro,data=ordered
> 154 153 0:3 / /home/avagin/rootfs/root/proc rw,relatime - proc proc rw
> 
> So we see all host mounts, because we call pivot_root after chroot()
> and all mount under chroot have not been umounted.
> 
> >
> > -serge


More information about the lxc-devel mailing list