From: Michael Tremer Date: Fri, 9 Dec 2022 15:53:01 +0000 (+0000) Subject: jail: Create a new network namespace unless running interactively X-Git-Tag: 0.9.28~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bdf1d8efdcee619ea5089ee2fb684b94736cdf9;p=pakfire.git jail: Create a new network namespace unless running interactively This will deny any internet connectivity in the build environment, but will allow users in an interative shell to use the network. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index f57801f1e..0850698a0 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -107,7 +108,13 @@ struct pakfire_log_buffer { size_t used; }; +enum pakfire_jail_exec_flags { + PAKFIRE_JAIL_HAS_NETWORKING = (1 << 0), +}; + struct pakfire_jail_exec { + int flags; + // PID (of the child) pid_t pid; int pidfd; @@ -156,6 +163,11 @@ static int clone3(struct clone_args* args, size_t size) { return syscall(__NR_clone3, args, size); } +static int pakfire_jail_exec_has_flag( + const struct pakfire_jail_exec* ctx, const enum pakfire_jail_exec_flags flag) { + return ctx->flags & flag; +} + static void pakfire_jail_free(struct pakfire_jail* jail) { DEBUG(jail->pakfire, "Freeing jail at %p\n", jail); @@ -938,10 +950,29 @@ PAKFIRE_EXPORT int pakfire_jail_bind(struct pakfire_jail* jail, return 0; } +static int pakfire_jail_mount_networking(struct pakfire_jail* jail) { + int r; + + const char* paths[] = { + "/etc/hosts", + "/etc/resolv.conf", + NULL, + }; + + // Bind-mount all paths read-only + for (const char** path = paths; *path; path++) { + r = pakfire_bind(jail->pakfire, *path, NULL, MS_RDONLY); + if (r) + return r; + } + + return 0; +} + /* Mounts everything that we require in the new namespace */ -static int pakfire_jail_mount(struct pakfire_jail* jail) { +static int pakfire_jail_mount(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) { struct pakfire_jail_mountpoint* mp = NULL; int r; @@ -950,6 +981,13 @@ static int pakfire_jail_mount(struct pakfire_jail* jail) { if (r) return r; + // Mount networking stuff + if (pakfire_jail_exec_has_flag(ctx, PAKFIRE_JAIL_HAS_NETWORKING)) { + r = pakfire_jail_mount_networking(jail); + if (r) + return r; + } + // Mount all custom stuff for (unsigned int i = 0; i < jail->num_mountpoints; i++) { // Fetch mountpoint @@ -1236,7 +1274,7 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe // Change root (unless root is /) if (!pakfire_on_root(jail->pakfire)) { // Mount everything - r = pakfire_jail_mount(jail); + r = pakfire_jail_mount(jail, ctx); if (r) return r; @@ -1380,6 +1418,8 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], // Initialize context for this call struct pakfire_jail_exec ctx = { + .flags = 0, + .pipes = { .stdin = { 0, 0 }, .stdout = { 0, 0 }, @@ -1395,6 +1435,10 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], DEBUG(jail->pakfire, "Executing jail...\n"); + // Enable networking in interactive mode + if (interactive) + ctx.flags |= PAKFIRE_JAIL_HAS_NETWORKING; + /* Setup a file descriptor which can be used to notify the client that the parent has completed configuration. @@ -1475,6 +1519,11 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], args.cgroup = pakfire_cgroup_fd(ctx.cgroup); } + // Setup networking + if (!pakfire_jail_exec_has_flag(&ctx, PAKFIRE_JAIL_HAS_NETWORKING)) { + args.flags |= CLONE_NEWNET; + } + // Fork this process ctx.pid = clone3(&args, sizeof(args)); if (ctx.pid < 0) {