From e42df368840ce96a4d561b4fec4d4ea07c30dbb6 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sun, 29 Nov 2020 20:16:36 +0300 Subject: change name to voidnsrun, add command-line arguments, rewrite readme --- glibcrun.c | 101 ------------------------------------------------------------- 1 file changed, 101 deletions(-) delete mode 100644 glibcrun.c (limited to 'glibcrun.c') diff --git a/glibcrun.c b/glibcrun.c deleted file mode 100644 index efedba1..0000000 --- a/glibcrun.c +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright (c) 2020 Evgeny Zinoviev . - * - * This program is licensed under the BSD 2-Clause License. - * https://opensource.org/licenses/BSD-2-Clause - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *var_name = "GLIBCRUN_DIR"; - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define ERROR(f_, ...) fprintf(stderr, (f_), ##__VA_ARGS__) - -int main(int argc, char *argv[]) { - int result; - - /* Get glibc base path */ - const char *dir = getenv(var_name); - if (!dir) { - ERROR("error: environment variable %s not found.\n", var_name); - return 1; - } - - /* Validate it */ - struct stat st; - result = stat(dir, &st); - if (result != 0 || !S_ISDIR(st.st_mode)) { - ERROR("error: %s is not a directory.\n", dir); - return 1; - } - - /* Get shell from current env to reuse it if needed */ - const char *shell = getenv("SHELL"); - if (!shell) - shell = "/bin/sh"; - - /* Do the unshare magic */ - result = unshare(CLONE_NEWNS); - if (result == -1) { - ERROR("unshare: %s\n", strerror(errno)); - return 1; - } - - /* Mount glibc stuff to our private namespace */ - const char *const mountpoints[] = {"/usr", "/var/db/xbps"}; - char buf[PATH_MAX]; - - for (int i = 0; i < (int)ARRAY_SIZE(mountpoints); i++) { - strcpy(buf, dir); - strcat(buf, mountpoints[i]); - result = mount(buf, mountpoints[i], NULL, MS_BIND|MS_REC, NULL); - if (result == -1) { - ERROR("mount(%s): %s\n", mountpoints[i], strerror(errno)); - return 1; - } - } - - /* Drop root */ - uid_t uid = getuid(); - gid_t gid = getgid(); - - result = setreuid(uid, uid); - if (result == -1) { - ERROR("setreuid: %s\n", strerror(errno)); - return 1; - } - - result = setregid(gid, gid); - if (result == -1) { - ERROR("setregid: %s\n", strerror(errno)); - return 1; - } - - /* Launch program or shell */ - const char *exec_cmd; - char *const *exec_args = NULL; - if (argc < 2) - exec_cmd = shell; - else { - exec_cmd = argv[1]; - exec_args = (char *const *)argv+1; - } - - result = execvp(exec_cmd, exec_args); - if (result == -1) { - ERROR("execvp(%s): %s\n", exec_cmd, strerror(errno)); - return 1; - } - - return 0; -} -- cgit v1.2.3