From 38d3fe573f4d0ad2115eaca71a0b8f67fd01a580 Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 30 Nov 2017 06:42:49 +0100 Subject: build-sandbox: Move to top-level build-support This is not only useful for packaging games, so let's make it available from the vuizvui scope, so we can use it from other packages as well. Signed-off-by: aszlig --- pkgs/games/build-support/build-sandbox/default.nix | 75 --- .../games/build-support/build-sandbox/src/Makefile | 23 - .../build-support/build-sandbox/src/nix-query.cc | 118 ---- .../build-support/build-sandbox/src/nix-query.h | 6 - .../games/build-support/build-sandbox/src/params.h | 10 - .../build-support/build-sandbox/src/path-cache.cc | 21 - .../build-support/build-sandbox/src/path-cache.h | 10 - .../build-support/build-sandbox/src/sandbox.c | 21 - pkgs/games/build-support/build-sandbox/src/setup.c | 709 --------------------- pkgs/games/build-support/build-sandbox/src/setup.h | 14 - pkgs/games/build-support/default.nix | 3 +- 11 files changed, 2 insertions(+), 1008 deletions(-) delete mode 100644 pkgs/games/build-support/build-sandbox/default.nix delete mode 100644 pkgs/games/build-support/build-sandbox/src/Makefile delete mode 100644 pkgs/games/build-support/build-sandbox/src/nix-query.cc delete mode 100644 pkgs/games/build-support/build-sandbox/src/nix-query.h delete mode 100644 pkgs/games/build-support/build-sandbox/src/params.h delete mode 100644 pkgs/games/build-support/build-sandbox/src/path-cache.cc delete mode 100644 pkgs/games/build-support/build-sandbox/src/path-cache.h delete mode 100644 pkgs/games/build-support/build-sandbox/src/sandbox.c delete mode 100644 pkgs/games/build-support/build-sandbox/src/setup.c delete mode 100644 pkgs/games/build-support/build-sandbox/src/setup.h (limited to 'pkgs/games/build-support') diff --git a/pkgs/games/build-support/build-sandbox/default.nix b/pkgs/games/build-support/build-sandbox/default.nix deleted file mode 100644 index fa4bac57..00000000 --- a/pkgs/games/build-support/build-sandbox/default.nix +++ /dev/null @@ -1,75 +0,0 @@ -{ stdenv, lib, pkgconfig, nix }: - -drv: { paths ? {}, ... }@attrs: - -let - # Extra paths that are required so they are created prior to bind-mounting. - pathsRequired = paths.required or []; - # Extra paths that are skipped if they don't exist. - pathsWanted = paths.wanted or []; - # Paths extracted from PATH-like environment variables, eg. LD_LIBRARY_PATH. - pathsRuntimeVars = paths.runtimeVars or []; - - # Create code snippets for params.c to add extra_mount() calls. - mkExtraMountParams = isRequired: lib.concatMapStringsSep "\n" (extra: let - escaped = lib.escape ["\\" "\""] extra; - reqBool = if isRequired then "true" else "false"; - code = "if (!extra_mount(\"${escaped}\", ${reqBool})) return false;"; - in "echo ${lib.escapeShellArg code} >> params.c"); - -in stdenv.mkDerivation ({ - name = "${drv.name}-sandboxed"; - - src = ./src; - - inherit drv; - - exportReferencesGraph = [ "sandbox-closure" drv ]; - - configurePhase = '' - runtimeDeps="$(sed -ne ' - p; n; n - - :cdown - /^0*$/b - :l; s/0\(X*\)$/X\1/; tl - - s/^\(X*\)$/9\1/; tdone - ${lib.concatMapStrings (num: '' - s/${toString num}\(X*\)$/${toString (num - 1)}\1/; tdone - '') (lib.range 1 9)} - - :done - y/X/9/ - x; n; p; x - bcdown - ' ../sandbox-closure | sort -u)" - - echo '#include "setup.h"' > params.c - echo 'bool setup_app_paths(void) {' >> params.c - - for dep in $runtimeDeps; do - echo 'if (!bind_mount("'"$dep"'", true, true)) return false;' >> params.c - done - - ${mkExtraMountParams true pathsRequired} - ${mkExtraMountParams false pathsWanted} - - echo 'return true; }' >> params.c - - echo 'bool mount_runtime_path_vars(struct query_state *qs) {' >> params.c - - ${lib.concatMapStringsSep "\n" (pathvar: let - escaped = lib.escapeShellArg (lib.escape ["\\" "\""] pathvar); - fun = "mount_from_path_var"; - result = "echo 'if (!${fun}(qs, \"'${escaped}'\")) return false;'"; - in "${result} >> params.c") pathsRuntimeVars} - - echo 'return true; }' >> params.c - ''; - - nativeBuildInputs = [ pkgconfig ]; - buildInputs = [ nix ]; - makeFlags = [ "BINDIR=${drv}/bin" ]; - -} // removeAttrs attrs [ "paths" ]) diff --git a/pkgs/games/build-support/build-sandbox/src/Makefile b/pkgs/games/build-support/build-sandbox/src/Makefile deleted file mode 100644 index cd642b8e..00000000 --- a/pkgs/games/build-support/build-sandbox/src/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -BINARIES = $(wildcard $(BINDIR)/*) -WRAPPERS = $(subst $(BINDIR),$(out)/bin,$(BINARIES)) - -NIX_VERSION = `pkg-config --modversion nix-main | \ - sed -e 's/^\([0-9]\+\)\.\([0-9]\+\).*/\1\2/'` - -OBJECTS = nix-query.o path-cache.o params.o setup.o - -CFLAGS = -g -Wall -std=gnu11 -DFS_ROOT_DIR=\"$(out)\" -CXXFLAGS = -g -Wall -std=c++14 `pkg-config --cflags nix-main` -CXXFLAGS += -DNIX_VERSION=$(NIX_VERSION) -LDFLAGS = `pkg-config --libs nix-main` - -all: $(OBJECTS) - -$(out)/bin/%: CFLAGS += -DWRAPPED_PROGNAME=\"$(@F)\" -$(out)/bin/%: CFLAGS += -DWRAPPED_PATH=\"$(BINDIR)/$(@F)\" -$(out)/bin/%: $(OBJECTS) - mkdir -p $(out)/bin - $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $? sandbox.c - -.PHONY: install -install: $(WRAPPERS) diff --git a/pkgs/games/build-support/build-sandbox/src/nix-query.cc b/pkgs/games/build-support/build-sandbox/src/nix-query.cc deleted file mode 100644 index 71208693..00000000 --- a/pkgs/games/build-support/build-sandbox/src/nix-query.cc +++ /dev/null @@ -1,118 +0,0 @@ -#include - -#if NIX_VERSION >= 112 -#include -#endif -#include -#include -#include - -#if NIX_VERSION < 112 -#include -#include -#endif - -using namespace nix; - -struct query_state { -#if NIX_VERSION >= 112 - std::shared_ptr store; -#else - std::shared_ptr store; -#endif - PathSet paths; - PathSet::iterator iter; -}; - -static Path get_store_path(query_state *qs, Path path) -{ - Path canonicalized = canonPath(path, true); -#if NIX_VERSION >= 112 - return qs->store->toStorePath(canonicalized); -#else - return toStorePath(canonicalized); -#endif -} - -static Path get_ancestor(query_state *qs, Path path) -{ - size_t pos = 0; - std::string tmp; - - while (pos != std::string::npos) { - if ((pos = path.find('/', pos + 1)) != std::string::npos) { - Path current = path.substr(0, pos); - - if (!isLink(current)) - continue; - - try { - current = get_store_path(qs, current); - } catch (...) { - continue; - } - - return current; - } - } - - return get_store_path(qs, path); -} - -extern "C" { - struct query_state *new_query(void) - { - query_state *initial = new query_state(); -#if NIX_VERSION >= 112 - initial->store = openStore(); -#else - settings.processEnvironment(); - settings.loadConfFile(); - initial->store = openStore(false); -#endif - return initial; - } - - void free_query(query_state *qs) - { - delete qs; - } - - bool query_requisites(query_state *qs, const char *path) - { - Path query(path); - - try { - query = get_ancestor(qs, query); - -#if NIX_VERSION >= 112 - qs->store->computeFSClosure( - qs->store->followLinksToStorePath(query), - qs->paths, false, true - ); -#else - computeFSClosure( - *qs->store, followLinksToStorePath(query), - qs->paths, false, true - ); -#endif - } catch (Error &e) { - std::cerr << "Error while querying requisites for " - << query << ": " << e.what() - << std::endl; - return false; - } - - qs->iter = qs->paths.begin(); - - return true; - } - - const char *next_query_result(query_state *qs) - { - if (qs->iter == qs->paths.end()) - return NULL; - - return (qs->iter++)->c_str(); - } -} diff --git a/pkgs/games/build-support/build-sandbox/src/nix-query.h b/pkgs/games/build-support/build-sandbox/src/nix-query.h deleted file mode 100644 index 3eef7c4a..00000000 --- a/pkgs/games/build-support/build-sandbox/src/nix-query.h +++ /dev/null @@ -1,6 +0,0 @@ -struct query_state; - -struct query_state *new_query(void); -void free_query(struct query_state *qs); -bool query_requisites(struct query_state *qs, const char *path); -const char *next_query_result(struct query_state *qs); diff --git a/pkgs/games/build-support/build-sandbox/src/params.h b/pkgs/games/build-support/build-sandbox/src/params.h deleted file mode 100644 index ecfa7295..00000000 --- a/pkgs/games/build-support/build-sandbox/src/params.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _PARAMS_H -#define _PARAMS_H - -#include -#include "nix-query.h" - -bool setup_app_paths(void); -bool mount_runtime_path_vars(struct query_state *qs); - -#endif diff --git a/pkgs/games/build-support/build-sandbox/src/path-cache.cc b/pkgs/games/build-support/build-sandbox/src/path-cache.cc deleted file mode 100644 index 5bfa43a7..00000000 --- a/pkgs/games/build-support/build-sandbox/src/path-cache.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -typedef std::set *path_cache; - -extern "C" { - path_cache new_path_cache(void) - { - return new std::set(); - } - - void free_path_cache(path_cache pc) - { - delete pc; - } - - bool cache_path(path_cache pc, const char *path) - { - return pc->insert(std::string(path)).second; - } -} diff --git a/pkgs/games/build-support/build-sandbox/src/path-cache.h b/pkgs/games/build-support/build-sandbox/src/path-cache.h deleted file mode 100644 index 368f8d17..00000000 --- a/pkgs/games/build-support/build-sandbox/src/path-cache.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _PATH_CACHE_H -#define _PATH_CACHE_H - -typedef void *path_cache; - -path_cache new_path_cache(void); -void free_path_cache(path_cache pc); -bool cache_path(path_cache pc, const char *path); - -#endif diff --git a/pkgs/games/build-support/build-sandbox/src/sandbox.c b/pkgs/games/build-support/build-sandbox/src/sandbox.c deleted file mode 100644 index e2aa47cf..00000000 --- a/pkgs/games/build-support/build-sandbox/src/sandbox.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include - -#include "setup.h" - -int main(int argc, char **argv) -{ - if (!setup_sandbox()) - return 1; - - argv[0] = WRAPPED_PROGNAME; - if (execv(WRAPPED_PATH, argv) == -1) { - fprintf(stderr, "exec %s: %s\n", WRAPPED_PATH, strerror(errno)); - return 1; - } - - // Should never be reached. - return 1; -} diff --git a/pkgs/games/build-support/build-sandbox/src/setup.c b/pkgs/games/build-support/build-sandbox/src/setup.c deleted file mode 100644 index f351ce19..00000000 --- a/pkgs/games/build-support/build-sandbox/src/setup.c +++ /dev/null @@ -1,709 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "params.h" -#include "nix-query.h" -#include "path-cache.h" - -static path_cache cached_paths = NULL; - -static bool write_proc(int proc_pid_fd, const char *fname, const char *buf, - size_t buflen, bool ignore_errors) -{ - int fd; - - if ((fd = openat(proc_pid_fd, fname, O_WRONLY)) == -1) { - fprintf(stderr, "open %s: %s\n", fname, strerror(errno)); - return false; - } - - if (write(fd, buf, buflen) == -1) { - if (!ignore_errors) - fprintf(stderr, "write %s: %s\n", fname, strerror(errno)); - close(fd); - return ignore_errors; - } - - close(fd); - return true; -} - -#define WRITE_IDMAP(file, value) \ - buflen = snprintf(buf, 100, "%1$lu %1$lu 1", (unsigned long)value); \ - if (buflen >= 100) { \ - fputs("Unable to write buffer for " file ".\n", stderr); \ - close(proc_pid_fd); \ - return false; \ - } else if (buflen < 0) { \ - perror("snprintf " file " buffer"); \ - close(proc_pid_fd); \ - return false; \ - } \ - if (!write_proc(proc_pid_fd, file, buf, buflen, false)) { \ - close(proc_pid_fd); \ - return false; \ - } - -bool write_maps(pid_t parent_pid) -{ - int proc_pid_fd; - size_t buflen; - char buf[100]; - - buflen = snprintf(buf, 100, "/proc/%lu", (unsigned long)parent_pid); - if (buflen >= 100) { - fputs("Unable to write buffer for child pid proc path.\n", stderr); - return false; - } else if (buflen < 0) { - perror("snprintf child pid proc path"); - return false; - } - - if ((proc_pid_fd = open(buf, O_RDONLY | O_DIRECTORY)) == -1) { - fprintf(stderr, "open %s: %s\n", buf, strerror(errno)); - return false; - } - - WRITE_IDMAP("uid_map", geteuid()); - - // Kernels prior to Linux 3.19 which do not impose setgroups() - // restrictions won't have this file, so ignore failure. - write_proc(proc_pid_fd, "setgroups", "deny", 4, true); - - WRITE_IDMAP("gid_map", getegid()); - - return true; -} - -static bool makedirs(const char *path, bool do_cache) -{ - char *tmp, *segment; - - if ((tmp = strdup(path)) == NULL) { - fprintf(stderr, "strdup of %s: %s\n", path, strerror(errno)); - return false; - } - - segment = dirname(tmp); - - if (!(segment[0] == '/' && segment[1] == '\0')) { - if (!makedirs(segment, do_cache)) { - free(tmp); - return false; - } - } - - if (!do_cache || cache_path(cached_paths, path)) - (void)mkdir(path, 0755); - free(tmp); - return true; -} - -static char *get_mount_target(const char *path) -{ - size_t pathlen = strlen(path), rootdir_len = strlen(FS_ROOT_DIR); - char *target; - - if ((target = malloc(rootdir_len + pathlen + 1)) == NULL) { - perror("malloc mount target"); - return NULL; - } - - memcpy(target, FS_ROOT_DIR, rootdir_len); - memcpy(target + rootdir_len, path, pathlen + 1); - return target; -} - -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 ((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; -} - -static bool bind_file(const char *path) -{ - char *target, *tmp; - - if (access(path, R_OK) == -1) - // Skip missing mount source - return true; - - if ((target = get_mount_target(path)) == NULL) - return false; - - if ((tmp = strdup(target)) == NULL) { - perror("strdup bind file target path"); - free(target); - return false; - } - - if (!makedirs(dirname(tmp), true)) { - free(target); - free(tmp); - return false; - } - - free(tmp); - - if (!cache_path(cached_paths, path)) { - free(target); - return true; - } - - if (creat(target, 0666) == -1) { - fprintf(stderr, "unable to create %s: %s\n", target, strerror(errno)); - free(target); - return false; - } - - if (mount(path, target, "", MS_BIND, NULL) == -1) { - fprintf(stderr, "mount file %s to %s: %s\n", - path, target, strerror(errno)); - free(target); - return false; - } - - free(target); - return true; -} - -struct envar_offset { - int start; - int length; - int var_start; - int var_length; - struct envar_offset *next; -}; - -static struct envar_offset *alloc_offset(void) -{ - struct envar_offset *new_offset; - new_offset = malloc(sizeof(struct envar_offset)); - - if (new_offset == NULL) { - perror("malloc envar_offset"); - return NULL; - } - - new_offset->next = NULL; - return new_offset; -} - -static struct envar_offset *push_offset(struct envar_offset *current, - struct envar_offset **base) -{ - if (current == NULL) { - if ((current = alloc_offset()) != NULL) - *base = current; - return current; - } - - return current->next = alloc_offset(); -} - -static void free_offsets(struct envar_offset *base) -{ - struct envar_offset *next; - if (base == NULL) - return; - next = base->next; - free(base); - if (next != NULL) - free_offsets(next); -} - -static char *expand_xdg_fallback(const char *xdg_var) -{ - static char *home = NULL; - static size_t homelen; - char *result; - - if (home == NULL) { - if ((home = getenv("HOME")) == NULL) { - fputs("Unable find $HOME.\n", stderr); - return NULL; - } - homelen = strlen(home); - } - - if (strcmp(xdg_var, "XDG_DATA_HOME") == 0) { - result = malloc(homelen + 14); - if (result == NULL) { - perror("malloc XDG_DATA_HOME"); - return NULL; - } - memcpy(result, home, homelen); - memcpy(result + homelen, "/.local/share", 14); - return result; - } else if (strcmp(xdg_var, "XDG_CONFIG_HOME") == 0) { - result = malloc(homelen + 9); - if (result == NULL) { - perror("malloc XDG_CONFIG_HOME"); - return NULL; - } - memcpy(result, home, homelen); - memcpy(result + homelen, "/.config", 9); - return result; - } - - return NULL; -} - -static char *get_offset_var(struct envar_offset *offset, const char *haystack) -{ - char *tmp, *result; - - tmp = strndup(haystack + offset->var_start, offset->var_length); - - if (tmp == NULL) { - perror("strndup"); - return NULL; - } - - result = getenv(tmp); - if (result == NULL) { - if ((result = expand_xdg_fallback(tmp)) == NULL) { - fprintf(stderr, "Unable find variable %s in %s\n", tmp, haystack); - free(tmp); - return NULL; - } - free(tmp); - return result; - } - free(tmp); - return strdup(result); -} - -static char *replace_env_offset_free(const char *path, - struct envar_offset *offset) -{ - struct envar_offset *tmp_offset; - size_t buflen, pathlen, varlen, tmplen; - int inpos = 0, outpos = 0; - char *buf, *curvar; - - buflen = pathlen = strlen(path); - - if ((buf = malloc(buflen + 1)) == NULL) { - perror("malloc replace_env buffer"); - return NULL; - } - - while (offset != NULL) { - if ((curvar = get_offset_var(offset, path)) == NULL) { - free(buf); - free_offsets(offset); - return NULL; - } - - varlen = strlen(curvar); - tmplen = varlen + (buflen - offset->length); - - if (tmplen > buflen) { - if ((buf = realloc(buf, (buflen = tmplen) + 1)) == NULL) { - perror("realloc replace_env buffer"); - free(buf); - free(curvar); - free_offsets(offset); - return NULL; - } - } - - memcpy(buf + outpos, path + inpos, offset->start - inpos); - outpos += offset->start - inpos; - inpos = offset->start; - - memcpy(buf + outpos, curvar, varlen); - outpos += varlen; - inpos += offset->length; - - free(curvar); - - tmp_offset = offset; - offset = offset->next; - free(tmp_offset); - } - - memcpy(buf + outpos, path + inpos, pathlen - inpos); - *(buf + outpos + (pathlen - inpos)) = '\0'; - - return buf; -} - -static char *replace_env(const char *path) -{ - int i = 0, start = 0, var_start = 0; - size_t pathlen; - bool in_var = false, curly = false; - struct envar_offset *base = NULL, *offset = NULL; - - pathlen = strlen(path); - - while (i < pathlen) { - if (path[i] == '$' && !curly && !in_var) { - if (i + 1 >= pathlen) - break; - - start = i; - - if (path[i + 1] == '{') { - curly = true; - var_start = i + 2; - ++i; - } else { - in_var = true; - var_start = i + 1; - } - } else if (in_var) { - if (!(path[i] >= 'a' && path[i] <= 'z') && - !(path[i] >= 'A' && path[i] <= 'Z') && - !(path[i] >= '0' && path[i] <= '9') && - path[i] != '_' - ) { - in_var = false; - - if ((offset = push_offset(offset, &base)) == NULL) { - free_offsets(base); - return NULL; - } - - offset->start = start; - offset->length = i - start; - offset->var_start = var_start; - offset->var_length = i - var_start; - continue; - } - } else if (curly) { - if (path[i] == '}') { - curly = false; - - if ((offset = push_offset(offset, &base)) == NULL) { - free_offsets(base); - return NULL; - } - - offset->start = start; - offset->length = (i + 1) - offset->start; - offset->var_start = var_start; - offset->var_length = i - offset->var_start; - } - } - - ++i; - } - - if (in_var) { - if ((offset = push_offset(offset, &base)) == NULL) { - free_offsets(base); - return NULL; - } - - offset->start = start; - offset->length = i - start; - offset->var_start = var_start; - offset->var_length = i - var_start; - } - - return replace_env_offset_free(path, base); -} - -bool extra_mount(const char *path, bool is_required) -{ - char *expanded; - - if ((expanded = replace_env(path)) == NULL) - return false; - - if (is_required && !makedirs(expanded, false)) - return false; - - if (!bind_mount(expanded, true, true)) { - free(expanded); - return false; - } - - free(expanded); - return true; -} - -static bool setup_xauthority(void) -{ - char *xauth, *home; - bool result; - size_t homelen; - - if ((xauth = getenv("XAUTHORITY")) != NULL) - return bind_file(xauth); - - if ((home = getenv("HOME")) == NULL) { - fputs("Unable find $HOME.\n", stderr); - return false; - } - - homelen = strlen(home); - - if ((xauth = malloc(homelen + 13)) == NULL) { - perror("malloc xauth file path"); - return false; - } - - memcpy(xauth, home, homelen); - memcpy(xauth + homelen, "/.Xauthority", 13); - - result = bind_file(xauth); - free(xauth); - return result; -} - -static bool is_dir(const char *path) -{ - struct stat sb; - if (stat(path, &sb) == -1) { - fprintf(stderr, "stat %s: %s\n", path, strerror(errno)); - // Default to directory for mounting - return true; - } - return S_ISDIR(sb.st_mode); -} - -static bool mount_requisites(struct query_state *qs, const char *path) -{ - const char *requisite; - - if (!query_requisites(qs, path)) { - fprintf(stderr, "Unable to get requisites for %s.\n", path); - return false; - } - - while ((requisite = next_query_result(qs)) != NULL) { - if (is_dir(requisite)) { - if (!bind_mount(requisite, true, false)) - return false; - } else { - if (!bind_file(requisite)) - return false; - } - } - - return true; -} - -bool mount_from_path_var(struct query_state *qs, const char *name) -{ - char *buf, *ptr, *value = getenv(name); - - if (value == NULL) - return true; - - if ((buf = strdup(value)) == NULL) { - fprintf(stderr, "strdup %s: %s\n", value, strerror(errno)); - return false; - } - - ptr = strtok(buf, ":"); - - while (ptr != NULL) { - if (!mount_requisites(qs, ptr)) { - free(buf); - return false; - } - ptr = strtok(NULL, ":"); - } - - free(buf); - return true; -} - -static bool setup_static_etc(struct query_state *qs) -{ - char dest[PATH_MAX]; - ssize_t destlen; - - if ((destlen = readlink("/etc/static", dest, PATH_MAX)) == -1) - return true; - - if (destlen >= PATH_MAX) { - fputs("readlink of /etc/static larger than PATH_MAX.\n", stderr); - return false; - } - - dest[destlen] = '\0'; - return mount_requisites(qs, dest); -} - -static bool setup_runtime_paths(void) -{ - struct query_state *qs; - - if ((qs = new_query()) == NULL) { - fputs("Unable to allocate Nix query state.\n", stderr); - return false; - } - - if (!setup_static_etc(qs)) { - free_query(qs); - return false; - } - - if (!mount_runtime_path_vars(qs)) { - free_query(qs); - return false; - } - - free_query(qs); - return true; -} - -static bool setup_chroot(void) -{ - int mflags; - - mflags = MS_NOEXEC | MS_NOSUID | MS_NODEV | MS_NOATIME; - - if (mount("none", FS_ROOT_DIR, "tmpfs", mflags, NULL) == -1) { - perror("mount rootfs"); - return false; - } - - if (!bind_mount("/etc", true, false)) - return false; - - if (!bind_mount("/dev", false, false)) - return false; - - if (!bind_mount("/proc", false, false)) - return false; - - if (!bind_mount("/sys", false, false)) - return false; - - if (!bind_mount("/run", false, false)) - return false; - - if (!bind_mount("/var/run", false, false)) - return false; - - if (!bind_mount("/tmp", true, false)) - return false; - - if (!setup_runtime_paths()) - return false; - - if (!setup_app_paths()) - return false; - - if (!setup_xauthority()) - return false; - - if (chroot(FS_ROOT_DIR) == -1) { - perror("chroot"); - return false; - } - - if (chdir("/") == -1) { - perror("chdir rootfs"); - return false; - } - - return true; -} - -bool setup_sandbox(void) -{ - int sync_pipe[2]; - char sync_status = '.'; - int child_status; - pid_t pid, parent_pid; - - if (pipe(sync_pipe) == -1) { - perror("pipe"); - return false; - } - - parent_pid = getpid(); - - switch (pid = fork()) { - case -1: - perror("fork"); - return false; - case 0: - close(sync_pipe[1]); - if (read(sync_pipe[0], &sync_status, 1) == -1) { - perror("read pipe from parent"); - _exit(1); - } else if (sync_status == 'X') - _exit(1); - close(sync_pipe[0]); - _exit(write_maps(parent_pid) ? 0 : 1); - default: - if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1) { - perror("unshare"); - if (write(sync_pipe[1], "X", 1) == -1) - perror("signal child exit"); - waitpid(pid, NULL, 0); - return false; - } - - close(sync_pipe[1]); - waitpid(pid, &child_status, 0); - if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) - break; - return false; - } - - cached_paths = new_path_cache(); - - if (!setup_chroot()) { - free_path_cache(cached_paths); - return false; - } - - free_path_cache(cached_paths); - return true; -} diff --git a/pkgs/games/build-support/build-sandbox/src/setup.h b/pkgs/games/build-support/build-sandbox/src/setup.h deleted file mode 100644 index fe882dc5..00000000 --- a/pkgs/games/build-support/build-sandbox/src/setup.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _SETUP_H -#define _SETUP_H - -#include -#include -#include "nix-query.h" - -bool write_maps(pid_t parent_pid); -bool bind_mount(const char *path, bool restricted, bool resolve); -bool extra_mount(const char *path, bool is_required); -bool mount_from_path_var(struct query_state *qs, const char *name); -bool setup_sandbox(void); - -#endif diff --git a/pkgs/games/build-support/default.nix b/pkgs/games/build-support/default.nix index 3017fe8e..e739c25f 100644 --- a/pkgs/games/build-support/default.nix +++ b/pkgs/games/build-support/default.nix @@ -4,6 +4,7 @@ buildGame = callPackage ./build-game.nix { withPulseAudio = config.pulseaudio or true; }; - buildSandbox = callPackage ./build-sandbox {}; + # XXX: Pass through from parent scope! + buildSandbox = callPackage ../../build-support/build-sandbox {}; buildUnity = callPackage ./build-unity.nix {}; } -- cgit 1.4.1