]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
jail: Create a new network namespace unless running interactively
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 9 Dec 2022 15:53:01 +0000 (15:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 9 Dec 2022 15:53:01 +0000 (15:53 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/jail.c

index f57801f1ef67adaf46e7ac742cfbd64fa939003b..0850698a0245c43abfad91020fc1f69661f3a5dd 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/capability.h>
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
+#include <sys/mount.h>
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -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) {