#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>
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;
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);
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;
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
// 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;
// Initialize context for this call
struct pakfire_jail_exec ctx = {
+ .flags = 0,
+
.pipes = {
.stdin = { 0, 0 },
.stdout = { 0, 0 },
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.
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) {