From feb8d535410a59f29ef9f9ec1ad17c393ecac67b Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 30 Nov 2017 07:35:51 +0100 Subject: 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 --- pkgs/build-support/build-sandbox/src/setup.c | 76 ++++++++++++++++------------ 1 file changed, 43 insertions(+), 33 deletions(-) (limited to 'pkgs/build-support/build-sandbox') 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; -- cgit 1.4.1