From df92b9457bac64656a701f88e19240dbd639ab46 Mon Sep 17 00:00:00 2001 From: Thomas Coldrick Date: Fri, 8 Nov 2019 15:24:00 +0000 Subject: _sandboxbwrap.py: Create /dev/shm in the sandbox Creates /dev/shm as a tmpfs in the sandbox. Before now access to /dev/shm was only available by a plugin using `Sandbox.mark_directory()` or adding to `Sandbox.DEVICES`, either of which would _mount_ /dev/shm into the sandbox, allowing pollution from the host. This adds it as a tmpfs by default, which seems sensible as it is required for POSIX support. Also adds a test which makes sure that we can open a shared memory object inside the build sandbox with some (probably poor) C code. --- src/buildstream/sandbox/_sandboxbwrap.py | 9 +++++-- .../elements/sandbox-bwrap/test-dev-shm.bst | 15 +++++++++++ tests/integration/project/files/test_shm.c | 29 ++++++++++++++++++++++ tests/integration/sandbox-bwrap.py | 11 ++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/integration/project/elements/sandbox-bwrap/test-dev-shm.bst create mode 100644 tests/integration/project/files/test_shm.c diff --git a/src/buildstream/sandbox/_sandboxbwrap.py b/src/buildstream/sandbox/_sandboxbwrap.py index bd60eafc1..5c4b9a295 100644 --- a/src/buildstream/sandbox/_sandboxbwrap.py +++ b/src/buildstream/sandbox/_sandboxbwrap.py @@ -207,6 +207,11 @@ class SandboxBwrap(Sandbox): for device in self.DEVICES: bwrap_command += ['--dev-bind', device, device] + # Create a tmpfs for /dev/shm, if we're in interactive this + # is handled by `--dev /dev` + # + bwrap_command += ['--tmpfs', '/dev/shm'] + # Add bind mounts to any marked directories marked_directories = self._get_marked_directories() mount_source_overrides = self._get_mount_sources() @@ -260,7 +265,7 @@ class SandboxBwrap(Sandbox): # existing_basedirs = { directory: os.path.exists(os.path.join(root_directory, directory)) - for directory in ['tmp', 'dev', 'proc'] + for directory in ['dev/shm', 'tmp', 'dev', 'proc'] } # Use the MountMap context manager to ensure that any redirected @@ -294,7 +299,7 @@ class SandboxBwrap(Sandbox): # Remove /tmp, this is a bwrap owned thing we want to be sure # never ends up in an artifact - for basedir in ['tmp', 'dev', 'proc']: + for basedir in ['dev/shm', 'tmp', 'dev', 'proc']: # Skip removal of directories which already existed before # launching bwrap diff --git a/tests/integration/project/elements/sandbox-bwrap/test-dev-shm.bst b/tests/integration/project/elements/sandbox-bwrap/test-dev-shm.bst new file mode 100644 index 000000000..03dc74a35 --- /dev/null +++ b/tests/integration/project/elements/sandbox-bwrap/test-dev-shm.bst @@ -0,0 +1,15 @@ +kind: manual + +depends: +- base.bst + +config: + build-commands: + - cc test_shm.c + + install-commands: + - ./a.out + +sources: +- kind: local + path: files/test_shm.c diff --git a/tests/integration/project/files/test_shm.c b/tests/integration/project/files/test_shm.c new file mode 100644 index 000000000..4ee71cb2b --- /dev/null +++ b/tests/integration/project/files/test_shm.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main () +{ + int fd = shm_open ("/foo", O_RDONLY | O_CREAT, S_IRWXU); + if (fd < 0) + { + fprintf (stderr, "Failed to open shm: %s\n", strerror (errno)); + exit(1); + } + + int success = shm_unlink ("/foo"); + if (success < 0) + { + fprintf (stderr, "Failed to close shm: %s\n", strerror (errno)); + exit(2); + } + + close (fd); + + return 0; +} diff --git a/tests/integration/sandbox-bwrap.py b/tests/integration/sandbox-bwrap.py index f48c75cbd..00fdd707c 100644 --- a/tests/integration/sandbox-bwrap.py +++ b/tests/integration/sandbox-bwrap.py @@ -60,3 +60,14 @@ def test_sandbox_bwrap_return_subprocess(cli, datafiles): result = cli.run(project=project, args=['build', element_name]) result.assert_task_error(error_domain=ErrorDomain.SANDBOX, error_reason="command-failed") assert "sandbox-bwrap/command-exit-42.bst|Command failed with exitcode 42" in result.stderr + +@pytest.mark.skipif(HAVE_SANDBOX != 'bwrap', reason='Only available with bubblewrap') +@pytest.mark.datafiles(DATA_DIR) +def test_sandbox_bwrap_dev_shm(cli, datafiles): + project = str(datafiles) + element_name = 'sandbox-bwrap/test-dev-shm.bst' + + result = cli.run(project=project, args=['build', element_name]) + assert result.exit_code == 0 + + -- cgit v1.2.1