You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by tv...@apache.org on 2021/11/03 10:29:30 UTC

[buildstream] 01/04: _sandboxbwrap.py: Create /dev/shm in the sandbox

This is an automated email from the ASF dual-hosted git repository.

tvb pushed a commit to branch tristan/bst-1/bwrap-dev-shm
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit 811d94b012f56b0ad2c9981aecf64e20f6f73a42
Author: Thomas Coldrick <co...@protonmail.com>
AuthorDate: Fri Jan 17 21:18:28 2020 +0000

    _sandboxbwrap.py: Create /dev/shm in the sandbox
    
    Create /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.
    
    Backport of !1694
---
 buildstream/sandbox/_sandboxbwrap.py               | 10 ++++++--
 buildstream/sandbox/sandbox.py                     |  8 +++++++
 .../elements/sandbox-bwrap/test-dev-shm.bst        | 15 ++++++++++++
 tests/integration/project/files/test_shm.c         | 28 ++++++++++++++++++++++
 tests/integration/sandbox-bwrap.py                 | 10 ++++++++
 5 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/buildstream/sandbox/_sandboxbwrap.py b/buildstream/sandbox/_sandboxbwrap.py
index cb570ef..291fce1 100644
--- a/buildstream/sandbox/_sandboxbwrap.py
+++ b/buildstream/sandbox/_sandboxbwrap.py
@@ -158,6 +158,12 @@ 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`
+        #
+        if flags & SandboxFlags.CREATE_DEV_SHM:
+            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()
@@ -196,7 +202,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
@@ -236,7 +242,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/buildstream/sandbox/sandbox.py b/buildstream/sandbox/sandbox.py
index 7e1e32b..7c0ac88 100644
--- a/buildstream/sandbox/sandbox.py
+++ b/buildstream/sandbox/sandbox.py
@@ -68,6 +68,14 @@ class SandboxFlags():
     namespace where available.
     """
 
+    CREATE_DEV_SHM = 0x10
+    """Whether to create /dev/shm in the sandbox.
+
+    This allows plugins to create /dev/shm in the sandbox. This flag
+    was added to fix a bug in which /dev/shm was not added in, meaning our
+    sandbox was not POSIX compliant.
+    """
+
 
 class Sandbox():
     """Sandbox()
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 0000000..b9ab5ae
--- /dev/null
+++ b/tests/integration/project/elements/sandbox-bwrap/test-dev-shm.bst
@@ -0,0 +1,15 @@
+kind: manual
+
+depends:
+- base.bst
+
+config:
+  build-comamnds:
+  - 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 0000000..9d9dcea
--- /dev/null
+++ b/tests/integration/project/files/test_shm.c
@@ -0,0 +1,28 @@
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fnctl.h>
+
+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 7d2a184..d245a18 100644
--- a/tests/integration/sandbox-bwrap.py
+++ b/tests/integration/sandbox-bwrap.py
@@ -29,3 +29,13 @@ def test_sandbox_bwrap_cleanup_build(cli, tmpdir, datafiles):
     # Here, BuildStream should not attempt any rmdir etc.
     result = cli.run(project=project, args=['build', element_name])
     assert result.exit_code == 0
+
+
+@pytest.mark.skipif(not HAVE_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