]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Set up the loopback interface
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 5 May 2023 10:23:39 +0000 (10:23 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 5 May 2023 10:24:49 +0000 (10:24 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
configure.ac
src/libpakfire/jail.c

index 8a72f7309b59c47bd783e0ff7803454670eb3826..5e6dd36fa2e100973d8bdc14f9f9bcd09855efb8 100644 (file)
@@ -309,6 +309,8 @@ libpakfire_la_CFLAGS = \
        $(JSON_C_CFLAGS) \
        $(MAGIC_CFLAGS) \
        $(MOUNT_CFLAGS) \
+       $(NL3_CFLAGS) \
+       $(NL3_ROUTE_CFLAGS) \
        $(OPENSSL_CFLAGS) \
        $(PCRE2_CFLAGS) \
        $(SECCOMP_CFLAGS) \
@@ -340,6 +342,8 @@ libpakfire_la_LIBADD = \
        $(LZMA_LIBS) \
        $(MAGIC_LIBS) \
        $(MOUNT_LIBS) \
+       $(NL3_LIBS) \
+       $(NL3_ROUTE_LIBS) \
        $(OPENSSL_LIBS) \
        $(PCRE2_LIBS) \
        $(SECCOMP_LIBS) \
index 6700004cc6a204dc55829449078ee28c8b7abd6c..467fbad5636b3c605681054daae7316042ae02dc 100644 (file)
@@ -263,6 +263,8 @@ PKG_CHECK_MODULES([JSON_C], [json-c >= 0.15])
 PKG_CHECK_MODULES([LZMA], [liblzma])
 PKG_CHECK_MODULES([MAGIC], [libmagic])
 PKG_CHECK_MODULES([MOUNT], [mount])
+PKG_CHECK_MODULES([NL3], [libnl-3.0])
+PKG_CHECK_MODULES([NL3_ROUTE], [libnl-route-3.0])
 PKG_CHECK_MODULES([OPENSSL], [openssl >= 1.1.1])
 PKG_CHECK_MODULES([PCRE2], [libpcre2-8])
 PKG_CHECK_MODULES([SECCOMP], [libseccomp])
index d59a3574ee82c69dedbdf18d09d9e538b5ac6d9a..9c74f7381831251b0c9c19893ffc1bb35c8f2531 100644 (file)
 #include <sys/types.h>
 #include <sys/wait.h>
 
+// libnl3
+#include <net/if.h>
+#include <netlink/route/link.h>
+
 // libseccomp
 #include <seccomp.h>
 
@@ -1189,6 +1193,75 @@ static int pakfire_jail_mount(struct pakfire_jail* jail, struct pakfire_jail_exe
        return 0;
 }
 
+// Networking
+
+static int pakfire_jail_setup_loopback(struct pakfire_jail* jail) {
+       struct nl_sock* nl = NULL;
+       struct nl_cache* cache = NULL;
+       struct rtnl_link* link = NULL;
+       struct rtnl_link* change = NULL;
+       int r;
+
+       DEBUG(jail->pakfire, "Setting up loopback...\n");
+
+       // Allocate a netlink socket
+       nl = nl_socket_alloc();
+       if (!nl) {
+               ERROR(jail->pakfire, "Could not allocate a netlink socket: %m\n");
+               r = 1;
+               goto ERROR;
+       }
+
+       // Connect the socket
+       r = nl_connect(nl, NETLINK_ROUTE);
+       if (r) {
+               ERROR(jail->pakfire, "Could not connect netlink socket: %s\n", nl_geterror(r));
+               goto ERROR;
+       }
+
+       // Allocate the netlink cache
+       r = rtnl_link_alloc_cache(nl, AF_UNSPEC, &cache);
+       if (r < 0) {
+               ERROR(jail->pakfire, "Unable to allocate netlink cache: %s\n", nl_geterror(r));
+               goto ERROR;
+       }
+
+       // Fetch loopback interface
+       link = rtnl_link_get_by_name(cache, "lo");
+       if (!link) {
+               ERROR(jail->pakfire, "Could not find lo interface. Ignoring.\n");
+               r = 0;
+               goto ERROR;
+       }
+
+       // Allocate a new link
+       change = rtnl_link_alloc();
+       if (!change) {
+               ERROR(jail->pakfire, "Could not allocate change link\n");
+               r = 1;
+               goto ERROR;
+       }
+
+       // Set the link to UP
+       rtnl_link_set_flags(change, IFF_UP);
+
+       // Apply any changes
+       r = rtnl_link_change(nl, link, change, 0);
+       if (r) {
+               ERROR(jail->pakfire, "Unable to activate loopback: %s\n", nl_geterror(r));
+               goto ERROR;
+       }
+
+       // Success
+       r = 0;
+
+ERROR:
+       if (nl)
+               nl_socket_free(nl);
+
+       return r;
+}
+
 // UID/GID Mapping
 
 static int pakfire_jail_setup_uid_mapping(struct pakfire_jail* jail, pid_t pid) {
@@ -1457,6 +1530,13 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe
                }
        }
 
+       // Setup networking
+       if (!pakfire_jail_exec_has_flag(ctx, PAKFIRE_JAIL_HAS_NETWORKING)) {
+               r = pakfire_jail_setup_loopback(jail);
+               if (r)
+                       return 1;
+       }
+
        // Set nice level
        if (jail->nice) {
                DEBUG(jail->pakfire, "Setting nice level to %d\n", jail->nice);