summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xrun-sandbox7
-rw-r--r--sandboxlib/chroot.py22
-rw-r--r--sandboxlib/linux_user_chroot.py35
3 files changed, 61 insertions, 3 deletions
diff --git a/run-sandbox b/run-sandbox
index 2bea1d4..356d9f6 100755
--- a/run-sandbox
+++ b/run-sandbox
@@ -91,7 +91,12 @@ def run():
extra_env['AC_APP_NAME'] = manifest['name']
- executor.run_sandbox(rootfs_path, command, cwd=cwd, extra_env=extra_env)
+ sharing_config = executor.maximum_possible_isolation()
+
+ executor.run_sandbox(
+ rootfs_path, command, cwd=cwd, extra_env=extra_env,
+ **sharing_config)
+
else:
# We should at minimum handle filesystem trees as well.
raise RuntimeError(
diff --git a/sandboxlib/chroot.py b/sandboxlib/chroot.py
index 8495df1..7c79f5c 100644
--- a/sandboxlib/chroot.py
+++ b/sandboxlib/chroot.py
@@ -31,12 +31,32 @@ import sys
import sandboxlib
-def run_sandbox(rootfs_path, command, cwd=None, extra_env=None):
+def maximum_possible_isolation():
+ return {
+ 'network': 'undefined'
+ }
+
+
+def process_network_config(network):
+ # It'd be possible to implement network isolation on Linux using the
+ # clone() syscall. However, I prefer to have the 'chroot' backend behave
+ # the same on all platforms, and have separate Linux-specific backends to
+ # do Linux-specific stuff.
+
+ assert network == 'undefined', \
+ "'%s' is an unsupported value for 'network' in the 'chroot' backend. " \
+ "Network sharing cannot be be configured in this backend." % network
+
+
+def run_sandbox(rootfs_path, command, cwd=None, extra_env=None,
+ network='undefined'):
if type(command) == str:
command = [command]
env = sandboxlib.environment_vars(extra_env)
+ process_network_config(network)
+
pid = os.fork()
if pid == 0:
# Child process. It's a bit messy that we create a child process and
diff --git a/sandboxlib/linux_user_chroot.py b/sandboxlib/linux_user_chroot.py
index 7af7608..cbd15d3 100644
--- a/sandboxlib/linux_user_chroot.py
+++ b/sandboxlib/linux_user_chroot.py
@@ -21,7 +21,38 @@ import subprocess
import sandboxlib
-def run_sandbox(rootfs_path, command, cwd=None, extra_env=None):
+def maximum_possible_isolation():
+ return {
+ 'network': 'isolated',
+ }
+
+
+def process_network_config(network):
+ # Network isolation is pretty easy, we 'unshare' the network namespace, and
+ # nothing can access the network.
+
+ # Network 'sharing' is a lot harder to tie down: does it just mean 'not
+ # blocked'? Or does it mean 'working, with /etc/resolv.conf correctly set
+ # up'? So that's not handled yet.
+
+ supported_values = ['undefined', 'isolated']
+
+ assert network in supported_values, \
+ "'%s' is an unsupported value for 'network' in the " \
+ "'linux-user-chroot' backend. Supported values: %s" \
+ % (network, ', '.join(supported_values))
+
+ if network == 'isolated':
+ # This is all we need to do for network isolation
+ extra_linux_user_chroot_args = ['--unshare-net']
+ else:
+ extra_linux_user_chroot_args = []
+
+ return extra_linux_user_chroot_args
+
+
+def run_sandbox(rootfs_path, command, cwd=None, extra_env=None,
+ network='undefined'):
if type(command) == str:
command = [command]
@@ -29,6 +60,8 @@ def run_sandbox(rootfs_path, command, cwd=None, extra_env=None):
linux_user_chroot_args = []
+ linux_user_chroot_args += process_network_config(network)
+
if cwd is not None:
linux_user_chroot_args.extend(['--chdir', cwd])