]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: execute: Unshare environment when entering chroot
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 13 Jan 2021 23:43:38 +0000 (23:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 13 Jan 2021 23:43:38 +0000 (23:43 +0000)
The shell has networking enabled automatically.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
configure.ac
src/_pakfire/pakfire.c
src/libpakfire/execute.c
src/libpakfire/include/pakfire/execute.h
src/pakfire/builder.py

index 2c14addd8141846be14211a8483a2bfb843b614a..c2c5e30e5784450b1f6798759068a07668f0cc1c 100644 (file)
@@ -122,6 +122,7 @@ AC_CHECK_HEADERS([ \
        ctypes.h \
        math.h \
        regex.h \
+       sched.h \
        stdarg.h \
        stdlib.h \
        string.h \
@@ -136,7 +137,8 @@ AC_CHECK_FUNCS([ \
        personality \
        secure_getenv \
        strcmp \
-       strdup
+       strdup \
+       unshare
 ])
 
 save_LIBS="$LIBS"
index 28af1425cacf785d38194616a86c4f45f9d48bac..253f9972476d0ff5ea21906c9ec6906dc667e361 100644 (file)
@@ -351,12 +351,13 @@ static Py_ssize_t Pakfire_len(PakfireObject* self) {
 }
 
 static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject* kwds) {
-       char* kwlist[] = {"command", "environ", NULL};
+       char* kwlist[] = {"command", "environ", "enable_network", NULL};
 
        PyObject* command = NULL;
        PyObject* environ = NULL;
+       int enable_network = 0;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, &command, &environ))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Op", kwlist, &command, &environ, &enable_network))
                return NULL;
 
        // Check if command is a list
@@ -410,6 +411,7 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
 
        const char* argv[command_length + 1];
        char* envp[environ_length + 1];
+       int flags = 0;
 
        // Parse arguments
        for (unsigned int i = 0; i < command_length; i++) {
@@ -441,8 +443,12 @@ static PyObject* Pakfire_execute(PakfireObject* self, PyObject* args, PyObject*
        argv[command_length] = NULL;
        envp[environ_length] = NULL;
 
+       // Enable network?
+       if (enable_network)
+               flags |= PAKFIRE_EXECUTE_ENABLE_NETWORK;
+
        // Execute command
-       int r = pakfire_execute(self->pakfire, argv, envp, 0);
+       int r = pakfire_execute(self->pakfire, argv, envp, flags);
 
        // Cleanup
        for (unsigned int i = 0; envp[i]; i++)
index fa4f5256ddb39f9d84a026b550a5737d9f6d8117..ad75e05eeab0ee583425b1f185e71399ed9c9c18 100644 (file)
@@ -34,7 +34,9 @@
 
 static char* envp_empty[1] = { NULL };
 
-static int pakfire_execute_fork(Pakfire pakfire, const char* argv[], char* envp[]) {
+static int pakfire_execute_fork(Pakfire pakfire, const char* argv[], char* envp[], int flags) {
+       int r;
+
        pid_t pid = getpid();
 
        const char* root = pakfire_get_path(pakfire);
@@ -49,7 +51,7 @@ static int pakfire_execute_fork(Pakfire pakfire, const char* argv[], char* envp[
                DEBUG(pakfire, "        env     : %s\n", envp[i]);
 
        // Move /
-       int r = chroot(root);
+       r = chroot(root);
        if (r) {
                ERROR(pakfire, "chroot() to %s failed: %s\n", root, strerror(errno));
                return errno;
@@ -67,6 +69,19 @@ static int pakfire_execute_fork(Pakfire pakfire, const char* argv[], char* envp[
                return errno;
        }
 
+       // Unshare namespaces
+       int uflags = CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUTS;
+
+       // Enable network?
+       if (!(flags & PAKFIRE_EXECUTE_ENABLE_NETWORK))
+               uflags |= CLONE_NEWNET;
+
+       r = unshare(uflags);
+       if (r) {
+               ERROR(pakfire, "Could not run unshare(%d): %s\n", uflags, strerror(errno));
+               return errno;
+       }
+
        // exec() command
        r = execve(argv[0], (char**)argv, envp);
 
@@ -91,7 +106,7 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en
 
        // Child process
        } else if (pid == 0) {
-               int r = pakfire_execute_fork(pakfire, argv, envp);
+               int r = pakfire_execute_fork(pakfire, argv, envp, flags);
 
                ERROR(pakfire, "Forked process returned unexpectedly: %s\n",
                        strerror(r));
index 6fef62c172fe69c54a786210278693b24c27f48e..18fa0754beeff504afabba7f2a2cc63cb0b9838f 100644 (file)
@@ -26,4 +26,9 @@
 int pakfire_execute(Pakfire pakfire, const char* argv[], char* envp[], int flags);
 int pakfire_execute_command(Pakfire pakfire, const char* command, char* envp[], int flags);
 
+enum {
+       PAKFIRE_EXECUTE_NONE                    = 0,
+       PAKFIRE_EXECUTE_ENABLE_NETWORK  = 1,
+};
+
 #endif /* PAKFIRE_EXECUTE_H */
index 0eae84a245a5b26196ff2d740974c856d5b2aeb7..72f53a07fe4fc74984e1f1f94f3d26ff13d1ae3d 100644 (file)
@@ -525,4 +525,5 @@ class BuilderContext(object):
                self._install(packages)
 
                # Enter the shell
-               self.pakfire.execute(["/usr/bin/bash", "--login"], environ=self.environ)
+               self.pakfire.execute(["/usr/bin/bash", "--login"],
+                       environ=self.environ, enable_network=True)