weakbox

Create a weak container for running programs from a different Linux distribution
Log | Files | Refs | LICENSE

commit 8f7e0468e1fc92e57c8a77f1a49a67846fcce114
parent dd54254ac64c483e345552155334a45d2004632a
Author: Friedel Schön <[email protected]>
Date:   Thu, 11 Jul 2024 17:10:23 +0200

Makefile-binary to weakbox

Diffstat:
MMakefile | 5++---
Mweakbox.c | 57++++++++++++++++++++++++++++++++-------------------------
2 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ PREFIX = /usr .PHONY: all install clean -all: enter +all: weakbox weakbox.o: weakbox.c arg.h $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) @@ -16,4 +16,4 @@ install: weakbox weakbox.1 cp weakbox.1 $(PREFIX)/share/man/man1/ clean: - rm -f weakbox weakbox.1 -\ No newline at end of file + rm -f weakbox weakbox.o diff --git a/weakbox.c b/weakbox.c @@ -42,25 +42,30 @@ #define MAX_GROUPMAP 16 -static int open_printf(const char* file, const char* format, ...) { - FILE* fd; +static int open_printf(const char* file, int openopt, const char* format, ...) { + static char buffer[1024]; + int fd, size; va_list va; - if (!(fd = fopen(file, "w"))) { + if ((fd = open(file, openopt)) == -1) { return -1; } va_start(va, format); - vfprintf(fd, format, va); + size = vsnprintf(buffer, sizeof(buffer), format, va); va_end(va); - fclose(fd); + + if (write(fd, buffer, size) == -1) + return -1; + + close(fd); return 0; } static char* argv0; static __attribute__((noreturn)) void usage(int exitcode) { - printf("usage: %s [-hs] [-r path] [-b source[:target]] [-B source] [-u uid[:uid]] [-g gid[:gid]] command ...\n", argv0); + printf("usage: %s [-hs] [-r path] [-b source[:target]] [-B source] [-u uid[:uid]] [-g gid[:gid]] [var=value] command ...\n", argv0); exit(exitcode); } @@ -107,8 +112,9 @@ int main(int argc, char** argv) { (void) argc; getcwd(pwd, sizeof(pwd)); - argv0 = *argv; - linkexec = strcmp(argv0, MYSELF); + argv0 = *argv; + linkexec = (temp = strrchr(argv0, '/')) ? strcmp(++temp, MYSELF) : strcmp(argv0, MYSELF); + if (!linkexec) { ARGBEGIN switch (OPT) { @@ -163,9 +169,9 @@ int main(int argc, char** argv) { ARGEND } - usermap[usermap_count].source = flagr ? geteuid() : 0; + usermap[usermap_count].source = flagr ? 0: geteuid() ; usermap[usermap_count++].target = geteuid(); - groupmap[groupmap_count].source = flagr ? getegid() : 0; + groupmap[groupmap_count].source = flagr ? 0: getegid() ; groupmap[groupmap_count++].target = getegid(); if (!root) { @@ -179,33 +185,35 @@ int main(int argc, char** argv) { return 1; } - DEBUG("debug: setting setgroups-policy\n"); - if (open_printf(PATH_PROC_SETGROUPS, "deny") && errno != ENOENT) { - fprintf(stderr, "error: unable to set setgroups-policy: %s\n", strerror(errno)); - return 1; - } - for (int i = 0; i < usermap_count; i++) { DEBUG("debug: mapping user %d to %d\n", usermap[i].source, usermap[i].target); - if (open_printf(PATH_PROC_UIDMAP, "%u %u 1", usermap[i].source, usermap[i].target)) { + if (open_printf(PATH_PROC_UIDMAP, O_WRONLY, "%u %u 1", usermap[i].source, usermap[i].target)) { fprintf(stderr, "error: unable to map user %d to %d: %s\n", usermap[i].source, usermap[i].target, strerror(errno)); return 1; } } + DEBUG("debug: setting setgroups-policy\n"); + if (open_printf(PATH_PROC_SETGROUPS, O_WRONLY, "deny") && errno != ENOENT) { + fprintf(stderr, "error: unable to set setgroups-policy: %s\n", strerror(errno)); + return 1; + } + for (int i = 0; i < groupmap_count; i++) { DEBUG("debug: mapping group %d to %d\n", groupmap[i].source, groupmap[i].target); - if (open_printf(PATH_PROC_GIDMAP, "%u %u 1", groupmap[i].source, groupmap[i].target)) { + if (open_printf(PATH_PROC_GIDMAP, O_WRONLY, "%u %u 1", groupmap[i].source, groupmap[i].target)) { fprintf(stderr, "error: unable to map group %d to %d: %s\n", groupmap[i].source, groupmap[i].target, strerror(errno)); return 1; } } + DEBUG("debug: new current user: %d, group: %d\n", getuid(), getgid()); + char target[PATH_MAX]; for (int i = 0; i < bind_count; i++) { snprintf(target, sizeof(target), "%s/%s", root, bind[i].target); DEBUG("debug: mount '%s' to '%s'\n", bind[i].source, target); - if (mount(bind[i].source, target, NULL, MS_BIND | MS_REC, NULL)) { + if (mount(bind[i].source, target, NULL, MS_BIND | MS_REC | MS_PRIVATE, NULL)) { fprintf(stderr, "error: unable to bind '%s' to '%s': %s\n", bind[i].source, target, strerror(errno)); return 1; } @@ -224,12 +232,11 @@ int main(int argc, char** argv) { (void) chdir("/"); } - if (linkexec) { - // argv is never shifted - DEBUG("debug: executing '%s'...\n", argv0); - execvp(argv0, argv); - fprintf(stderr, "error: unable to execute '%s': %s\n", *argv, strerror(errno)); - } else if (*argv) { + if (*argv) { + while (*argv && strchr(*argv, '=')) { + putenv(*argv++); + } + DEBUG("debug: executing '%s'...\n", *argv); execvp(*argv, argv); fprintf(stderr, "error: unable to execute '%s': %s\n", *argv, strerror(errno));