about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2017-11-30 07:35:51 +0100
committeraszlig <aszlig@nix.build>2017-11-30 08:34:05 +0100
commitfeb8d535410a59f29ef9f9ec1ad17c393ecac67b (patch)
treecf53c808051c6bdb4fdf7a1d2cb2e00d8e833a04 /pkgs/build-support
parent38d3fe573f4d0ad2115eaca71a0b8f67fd01a580 (diff)
pkgs/sandbox: Handle mounting of regular files
While we already have support for mounting plain files, this is done on
a very specific basis, mainly the .Xauthority file.

Whenever we use bind_mount() and the file is a regular file, mounting
that file will fail. So let's actually do a stat on the file and decide
whether we want to do bind_file() or bind_mount().

I've stumbled on this because one of the store paths of the run time
dependency graph was a plain file and thus the sandbox wrapper was
unable to mount it.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/build-sandbox/src/setup.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/pkgs/build-support/build-sandbox/src/setup.c b/pkgs/build-support/build-sandbox/src/setup.c
index f351ce19..83876b2a 100644
--- a/pkgs/build-support/build-sandbox/src/setup.c
+++ b/pkgs/build-support/build-sandbox/src/setup.c
@@ -130,40 +130,11 @@ static char *get_mount_target(const char *path)
     return target;
 }
 
-bool bind_mount(const char *path, bool restricted, bool resolve)
+static bool is_regular_file(const char *path)
 {
-    int mflags = MS_BIND | MS_REC;
-    char src[PATH_MAX], *target;
-
-    if (restricted)
-        mflags |= MS_NOSUID | MS_NODEV | MS_NOATIME;
-
-    if (resolve ? realpath(path, src) == NULL : access(path, F_OK) == -1)
-        // Skip missing mount source
-        return true;
-
-    if ((target = get_mount_target(resolve ? src : path)) == NULL)
-        return false;
-
-    if (!makedirs(target, false)) {
-        free(target);
-        return false;
-    }
-
-    if (!cache_path(cached_paths, resolve ? src : path)) {
-        free(target);
-        return true;
-    }
-
-    if (mount(resolve ? src : path, target, "", mflags, NULL) == -1) {
-        fprintf(stderr, "mount %s to %s: %s\n",
-                resolve ? src : path, target, strerror(errno));
-        free(target);
-        return false;
-    }
-
-    free(target);
-    return true;
+    struct stat st;
+    stat(path, &st);
+    return S_ISREG(st.st_mode);
 }
 
 static bool bind_file(const char *path)
@@ -213,6 +184,45 @@ static bool bind_file(const char *path)
     return true;
 }
 
+bool bind_mount(const char *path, bool restricted, bool resolve)
+{
+    int mflags = MS_BIND | MS_REC;
+    char src[PATH_MAX], *target;
+
+    if (restricted)
+        mflags |= MS_NOSUID | MS_NODEV | MS_NOATIME;
+
+    if (resolve ? realpath(path, src) == NULL : access(path, F_OK) == -1)
+        // Skip missing mount source
+        return true;
+
+    if (is_regular_file(resolve ? src : path))
+        return bind_file(resolve ? src : path);
+
+    if ((target = get_mount_target(resolve ? src : path)) == NULL)
+        return false;
+
+    if (!makedirs(target, false)) {
+        free(target);
+        return false;
+    }
+
+    if (!cache_path(cached_paths, resolve ? src : path)) {
+        free(target);
+        return true;
+    }
+
+    if (mount(resolve ? src : path, target, "", mflags, NULL) == -1) {
+        fprintf(stderr, "mount %s to %s: %s\n",
+                resolve ? src : path, target, strerror(errno));
+        free(target);
+        return false;
+    }
+
+    free(target);
+    return true;
+}
+
 struct envar_offset {
     int start;
     int length;