Rootless Containers
pivot_root
From pivot_root(2):
pivot_root() changes the root directory and the current working
directory of each process or thread in the same mount namespace to
new_root if they point to the old root directory. (See also NOTES.)
On the other hand, pivot_root() does not change the caller's current
working directory (unless it is on the old root directory), and thus
it should be followed by a chdir("/") call.
As found in "Rootless Containers with runC" -- Aleksa Sarai
$ unshare -UrmunipCf bash
# These 2 are needed for pivot_root to work:
$ mount --make-rprivate /
$ mount --rbind rootfs/ rootfs/
# (not needed for pivot_root POC)
$ mount -t proc proc rootfs/proc
$ mount -t tmpfs tmpfs rootfs/dev
$ mount -t devpts -o newinstance devpts rootfs/dev/pts
$ # ... skipping over a lot more mounting ...
$ pivot_root rootfs/ rootfs/.pivot_root && cd /
$ mount --make-rprivate /.pivot_root && umount -l /.pivot_root
$ exec bash # finally