From 14df73885038a88ee30501b5124cb0603551cf53 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 17 Jul 2023 16:44:50 +0000 Subject: [PATCH] jail: Use pivot_root() again instead of chroot() Signed-off-by: Michael Tremer --- src/libpakfire/include/pakfire/mount.h | 2 + src/libpakfire/jail.c | 53 +++++++++++++++++++------- src/libpakfire/mount.c | 34 +++++++++++++++++ 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/libpakfire/include/pakfire/mount.h b/src/libpakfire/include/pakfire/mount.h index 39e8750b3..11638578f 100644 --- a/src/libpakfire/include/pakfire/mount.h +++ b/src/libpakfire/include/pakfire/mount.h @@ -25,6 +25,8 @@ #include +int pakfire_mount_make_mounpoint(struct pakfire* pakfire, const char* path); + int pakfire_bind(struct pakfire* pakfire, const char* src, const char* dst, int flags); int pakfire_mount_list(struct pakfire* pakfire); diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index af7de97dc..db37cf7df 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -172,6 +172,10 @@ static int pidfd_send_signal(int pidfd, int sig, siginfo_t* info, unsigned int f return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags); } +static int pivot_root(const char* new_root, const char* old_root) { + return syscall(SYS_pivot_root, new_root, old_root); +} + static int pakfire_jail_exec_has_flag( const struct pakfire_jail_exec* ctx, const enum pakfire_jail_exec_flags flag) { return ctx->flags & flag; @@ -1555,6 +1559,33 @@ static int pakfire_jail_parent(struct pakfire_jail* jail, struct pakfire_jail_ex return 0; } +static int pakfire_jail_switch_root(struct pakfire_jail* jail, const char* root) { + int r; + + // Change to the new root + r = chdir(root); + if (r) { + ERROR(jail->pakfire, "chdir(%s) failed: %m\n", root); + return r; + } + + // Switch Root! + r = pivot_root(".", "."); + if (r) { + ERROR(jail->pakfire, "Failed changing into the new root directory %s: %m\n", root); + return r; + } + + // Umount the old root + r = umount2(".", MNT_DETACH); + if (r) { + ERROR(jail->pakfire, "Could not umount the old root filesystem: %m\n"); + return r; + } + + return 0; +} + static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx, const char* argv[]) { int r; @@ -1601,6 +1632,11 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe const char* root = pakfire_get_path(jail->pakfire); const char* arch = pakfire_get_arch(jail->pakfire); + // Make root a mountpoint in the new mount namespace + r = pakfire_mount_make_mounpoint(jail->pakfire, root); + if (r) + return r; + // Change root (unless root is /) if (!pakfire_on_root(jail->pakfire)) { // Mount everything @@ -1608,19 +1644,10 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe if (r) return r; - // Call chroot() - r = chroot(root); - if (r) { - ERROR(jail->pakfire, "chroot() to %s failed: %m\n", root); - return 1; - } - - // Change directory to / - r = chdir("/"); - if (r) { - ERROR(jail->pakfire, "chdir() after chroot() failed: %m\n"); - return 1; - } + // chroot() + r = pakfire_jail_switch_root(jail, root); + if (r) + return r; } // Set personality diff --git a/src/libpakfire/mount.c b/src/libpakfire/mount.c index 9dd4af17d..1983cea3a 100644 --- a/src/libpakfire/mount.c +++ b/src/libpakfire/mount.c @@ -143,6 +143,40 @@ static const struct pakfire_symlink { { NULL }, }; +static int pakfire_mount_is_mountpoint(struct pakfire* pakfire, const char* path) { + // XXX THIS STILL NEEDS TO BE IMPLEMENTED + return 1; +} + +int pakfire_mount_make_mounpoint(struct pakfire* pakfire, const char* path) { + int r; + + // Check if path already is a mountpoint + r = pakfire_mount_is_mountpoint(pakfire, path); + switch (r) { + // Already is a mountpoint + case 0: + return 0; + + // Is not a mountpoint + case 1: + break; + + default: + ERROR(pakfire, "Could not determine whether %s is a mountpoint: %m\n", path); + return r; + } + + // Bind-mount to self + r = mount(path, path, NULL, MS_BIND|MS_REC, NULL); + if (r) { + ERROR(pakfire, "Could not make %s a mountpoint: %m\n", path); + return r; + } + + return 0; +} + /* Easy way to iterate through all mountpoints */ -- 2.39.5