A process sandboxing library written in Rust.
Please note that this sandboxing library is a work in progress and has not yet been reviewed for correctness and overall security, so use at your own risk.
At the time of writing, Arch Linux chose to enable unprivileged namespace
support with kernel version +5.1.8, meaning that gaol now finally works
on Arch Linux. However, it relies on a chroot
jail which is rather easy to
escape, and the API is also incompatible with std::command::Command
.
rusty-sandbox works as expected on macOS using more secure methods, but Linux
is unsupported and it does not allow for filesystem mapping and mounting nor
fine-grained access control.
- Spawn commands under a cloned process in a new namespace.
- Environment variables, arguments, and current working directory can be
configured via the standard
std::process::Command
builder. - Command stdio can be configured via the standard
std::process::Command
builder (this is currently unsupported until rust-lang/rust#44434 is resolved). - Multiple sandboxes can be spawned in multi-threaded programs without
interfering with each other (this is possible because
clone(2)
ensures process isolation between parent and sandbox). - Sandbox spawned in one thread doesn't elevate user privileges for all
other threads in the parent process, meaning other threads in Rust code
aren't inadvertently granted Super Cow Powers (this is possible because
setfsuid
andcapset
are per-thread rather than per-process, and any times that Bastille does callsetuid
, we are in a separate child process). - Unshare the user namespace (always on; will add the option to toggle
off if requested, should Bastille detect the process is
setuid
). - Unshare the network namespace (WIP, successfully unshares and creates a local loopback device, but the interface has some configuration issues).
- Unshare the PID namespace.
- Unshare the IPC namespace.
- Unshare the UTS (system hostname and NIS domain name) namespace.
- Set up filesystem sandbox:
- Canonicalize all paths in mappings (eliminating symlinks), create a new
tmpfs
mount point for the new root in$base_path
, create a dir$base_path/new_root
,pivot_root()
to$base_path
, put the old root in$base_path/old_root
. Next, set upnew_root
with all the mounts, directories, symlinks, etc. andpivot_root()
again to/new_root
, unmount/old_root
, and unshare mount permissions.
- Canonicalize all paths in mappings (eliminating symlinks), create a new
- Add macOS backend using
sandboxd
(very heavy WIP). - Add FreeBSD backend using
capsicum
(don't have a box to test with ATM). - Add OpenBSD backend using
pledge
(don't have a box to test with ATM).
Design for the Linux backend implementation is loosely inspired by Bubblewrap.
Bastille is free and open source software distributed under the terms of the MIT and the Apache 2.0 licenses.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.