diff options
Diffstat (limited to 'internal/namespace/launcher_src')
| -rw-r--r-- | internal/namespace/launcher_src/launcher.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/namespace/launcher_src/launcher.c b/internal/namespace/launcher_src/launcher.c index 7bbbce7..60c6558 100644 --- a/internal/namespace/launcher_src/launcher.c +++ b/internal/namespace/launcher_src/launcher.c @@ -13,6 +13,69 @@ int main(int argc, char **argv) { return 1; } + // Check if we are joining an existing namespace + char *join_pid_str = getenv("WG_WRAP_JOIN_PID"); + if (join_pid_str != NULL && strlen(join_pid_str) > 0) { + int target_pid = atoi(join_pid_str); + if (target_pid > 0) { + char path[128]; + int fd; + + // 1. Join User Namespace first + snprintf(path, sizeof(path), "/proc/%d/ns/user", target_pid); + fd = open(path, O_RDONLY); + if (fd == -1) { + perror("open target user namespace"); + return 1; + } + if (setns(fd, CLONE_NEWUSER) == -1) { + perror("setns CLONE_NEWUSER"); + close(fd); + return 1; + } + close(fd); + + // 2. Join Mount Namespace + snprintf(path, sizeof(path), "/proc/%d/ns/mnt", target_pid); + fd = open(path, O_RDONLY); + if (fd == -1) { + perror("open target mount namespace"); + return 1; + } + if (setns(fd, CLONE_NEWNS) == -1) { + perror("setns CLONE_NEWNS"); + close(fd); + return 1; + } + close(fd); + + // 3. Join Network Namespace + snprintf(path, sizeof(path), "/proc/%d/ns/net", target_pid); + fd = open(path, O_RDONLY); + if (fd == -1) { + perror("open target network namespace"); + return 1; + } + if (setns(fd, CLONE_NEWNET) == -1) { + perror("setns CLONE_NEWNET"); + close(fd); + return 1; + } + close(fd); + + // Execute the target command + if (argv[0] == NULL) { + fprintf(stderr, "No target binary provided in argv[0]\n"); + return 1; + } + if (execv(argv[0], argv) == -1) { + perror("execv failed"); + return 1; + } + return 0; + } + } + // 1. Capture host identities BEFORE unsharing uid_t current_uid = getuid(); gid_t current_gid = getgid(); |
