The shell has networking enabled automatically.
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
ctypes.h \
math.h \
regex.h \
+ sched.h \
stdarg.h \
stdlib.h \
string.h \
personality \
secure_getenv \
strcmp \
- strdup
+ strdup \
+ unshare
])
save_LIBS="$LIBS"
}
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
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++) {
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++)
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);
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;
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);
// 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));
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 */
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)