This repository has a shell script to automate a common useful task for quarantining processes which are "poorly behaved" with respect to which files they modify in the underlying system, such as many build or install systems.
Disclaimer: This technique is not a security barrier.
This depends on the
unionfs-fuse tool, which is in a Debian/Ubuntu package of the same name.
Suppose you've just downloaded some software, but you don't have faith
that when you run
make install it won't clobber your base filesystem,
such as by overwriting a file in
/etc or otherwise interfering
with your distribution.
Packages with "well behaved" installers will accept an installation
target, and then they will only write files under that directory.
For example, packages distributed with
autoconf will typically
--prefix option to
./configure. How can you be
sure the package is well behaved?
You could read all the source code to the installation code, but this is time consuming. Furthermore, maybe this package is an opaque non-open-source distribution, such as for a proprietary driver.
Here is how to use this script to quarantine the installation and examine it after the fact:
$ unionfs-chroot Quarantining all fs writes into: /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox Running: sudo unionfs-fuse -o allow_other,use_ino,suid,dev,nonempty -ocow /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox=RW:/=RO /tmp/tmp.bQUprjB0zZ_unionfs-chroot.mountpoint Running: sudo chroot /tmp/tmp.bQUprjB0zZ_unionfs-chroot.mountpoint /bin/su - myuser $
The script tells us where it is saving all sandboxed writes to. We did
not specify a specific directory on the commandline, so it made a
temporary directory (ending with
We are actually now running in a sub-shell from the original shell as
Running: output shows. We can verify that we are in a
unionfs-chroot sandbox by looking for a specially named file:
$ cat /unionfs-chroot.sandbox /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox
This file contains the path in the outside world of the sandbox directory.
Now we can run the build process without worrying that a (non-malicious) installer will clobber our base system:
$ cd ./src/some_package $ make install
After this we can close this shell and examine the contents of the sandbox:
$ ^D Running: sudo umount /tmp/tmp.bQUprjB0zZ_unionfs-chroot.mountpoint
The script unmounts the unionfs and removes the (empty) mountpoint directory. Now we can do a sanity check that we are not inside a sandbox:
$ cat /unionfs-chroot.sandbox cat: /unionfs-chroot.sandbox: No such file or directory
Now we can see what the installer actually wrote to the filesystem:
$ cd /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox $ find
If we want to accept these modifications, we have two options:
Copying to integrate changes
We can "accept" the changes made by the installer by doing a recursive, attribute-preserving copy:
Warning: Make extra sure this is the right command. I have not tested this, and claim no responsibility for breaking your system! I chose to copy into
/usr/local in an attempt to avoid clobbering the base system's distro state.
Warning: If a file written into the sandbox would overwrite a base system file, it is possible that another process modified that underlying file while the installer was operating in the sandbox. In this case, copying the sandbox over the base system would erase some changes.
$ cp -a /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox/ /usr/local
Re-entering the sandboxed union mount
Another option is to re-enter the union mount every time you want to use the given software. This has the tradeoff that any data written by the installed package's processes (or any other processes invoked in the sandbox) will also be quarantined.
This might be useful, for example, if you want to run
firefox in two
different sandboxes to help ensure they are not leaking privacy-related
state between each sandbox.
The script accepts a sandbox as the first argument, so this allows us to re-use a sandbox:
$ unionfs-chroot.sh /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox Quarantining all fs writes into: /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox Running: sudo unionfs-fuse -o allow_other,use_ino,suid,dev,nonempty -ocow /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox=RW:/=RO /tmp/tmp.i5Qh33JoEl_unionfs-chroot.mountpoint Running: sudo chroot /tmp/tmp.i5Qh33JoEl_unionfs-chroot.mountpoint /bin/su - myuser $ cat /unionfs-chroot.sandbox /tmp/tmp.1GbGIk241B_unionfs-chroot.sandbox
Now you can run the "installed" package.
Q. Do recursive sandboxes work?
A. I don't know yet; I have not tested it.
Any other questions? Please contact the developer.