From 764d3e67fc783c487f42d398d1b85a5a1f0d8ef0 Mon Sep 17 00:00:00 2001 From: James O'Doherty Date: Fri, 22 May 2026 10:05:38 -0400 Subject: feat: implement rootless network isolation bootstrap and C launcher --- internal/namespace/launcher_src/launcher.c | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 internal/namespace/launcher_src/launcher.c (limited to 'internal/namespace/launcher_src/launcher.c') diff --git a/internal/namespace/launcher_src/launcher.c b/internal/namespace/launcher_src/launcher.c new file mode 100644 index 0000000..70737e4 --- /dev/null +++ b/internal/namespace/launcher_src/launcher.c @@ -0,0 +1,77 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc < 1) { + fprintf(stderr, "Usage: %s [args...]\n", argv[0]); + return 1; + } + + // 1. Capture host identities BEFORE unsharing + uid_t current_uid = getuid(); + gid_t current_gid = getgid(); + + // 2. Combined Unshare for User and Network namespaces + if (unshare(CLONE_NEWUSER | CLONE_NEWNET) == -1) { + perror("unshare(CLONE_NEWUSER | CLONE_NEWNET)"); + return 1; + } + + char map[64]; + + // 3. Write UID map + snprintf(map, sizeof(map), "0 %u 1\n", current_uid); + int fd = open("/proc/self/uid_map", O_WRONLY); + if (fd == -1) { + perror("open uid_map"); + return 1; + } + if (write(fd, map, strlen(map)) == -1) { + perror("write uid_map"); + close(fd); + return 1; + } + close(fd); + + // 4. Disable setgroups + fd = open("/proc/self/setgroups", O_WRONLY); + if (fd != -1) { + write(fd, "deny", 4); + close(fd); + } + + // 5. Write GID map + snprintf(map, sizeof(map), "0 %u 1\n", current_gid); + fd = open("/proc/self/gid_map", O_WRONLY); + if (fd == -1) { + perror("open gid_map"); + return 1; + } + if (write(fd, map, strlen(map)) == -1) { + perror("write gid_map"); + close(fd); + return 1; + } + close(fd); + + // 6. Execute the target command + // In this architecture, the Go Bootstrap code passes the target binary + // as the first element of the argv array. + // Therefore, argv[0] is the path to the binary we want to execute. + if (argv[0] == NULL) { + fprintf(stderr, "No target binary provided in argv[0]\n"); + return 1; + } + + fprintf(stderr, "[launcher] Executing binary: %s\n", argv[0]); + execvp(argv[0], argv); + + perror("execvp"); + return 1; +} -- cgit v1.2.3