From abe4ee370021acec84ba47eb45f03a2b0a13ab3d Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 31 Oct 2022 10:32:39 +0000 Subject: [PATCH] jail: Try to be smarter when mapping UID/GIDs This still doesn't work any I have absolutely no idea why. It shouldn't be a problem :( Signed-off-by: Michael Tremer --- src/libpakfire/jail.c | 68 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 1de30827f..e0d48d685 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -977,12 +977,6 @@ static int pakfire_jail_mount(struct pakfire_jail* jail) { // UID/GID Mapping -static int pakfire_jail_write_uidgid_mapping(struct pakfire_jail* jail, - const char* path, const struct pakfire_subid* subid) { - return pakfire_file_write(jail->pakfire, path, 0, 0, 0, - "%d %u %lu\n", 0, subid->id, subid->length); -} - static int pakfire_jail_setup_uid_mapping(struct pakfire_jail* jail, pid_t pid) { char path[PATH_MAX]; int r; @@ -991,20 +985,40 @@ static int pakfire_jail_setup_uid_mapping(struct pakfire_jail* jail, pid_t pid) if (pakfire_on_root(jail->pakfire)) return 0; + // Make path + r = pakfire_string_format(path, "/proc/%d/uid_map", pid); + if (r) + return r; + + // Fetch UID + const uid_t uid = pakfire_uid(jail->pakfire); + // Fetch SUBUID const struct pakfire_subid* subuid = pakfire_subuid(jail->pakfire); if (!subuid) return 1; - // Make path - r = pakfire_string_format(path, "/proc/%d/uid_map", pid); - if (r) - return r; + /* When running as root, we will map the entire range. - DEBUG(jail->pakfire, "Mapping UID range (%u - %lu)\n", - subuid->id, subuid->id + subuid->length); + When running as a non-privileged user, we will map the root user inside the jail + to the user's UID outside of the jail, and we will map the rest starting from one. + */ - return pakfire_jail_write_uidgid_mapping(jail, path, subuid); + // Running as root + if (uid == 0) { + r = pakfire_file_write(jail->pakfire, path, 0, 0, 0, + "0 %lu %lu\n", subuid->id, subuid->length); + } else { + r = pakfire_file_write(jail->pakfire, path, 0, 0, 0, + "0 %lu 1\n%1 %lu %lu\n", uid, subuid->id, subuid->length); + } + + if (r) { + ERROR(jail->pakfire, "Could not map UIDs: %m\n"); + return r; + } + + return r; } static int pakfire_jail_setup_gid_mapping(struct pakfire_jail* jail, pid_t pid) { @@ -1015,6 +1029,9 @@ static int pakfire_jail_setup_gid_mapping(struct pakfire_jail* jail, pid_t pid) if (pakfire_on_root(jail->pakfire)) return 0; + // Fetch GID + const gid_t gid = pakfire_gid(jail->pakfire); + // Fetch SUBGID const struct pakfire_subid* subgid = pakfire_subgid(jail->pakfire); if (!subgid) @@ -1025,10 +1042,21 @@ static int pakfire_jail_setup_gid_mapping(struct pakfire_jail* jail, pid_t pid) if (r) return r; - DEBUG(jail->pakfire, "Mapping GID range (%u - %lu)\n", - subgid->id, subgid->id + subgid->length); + // Running as root + if (gid == 0) { + r = pakfire_file_write(jail->pakfire, path, 0, 0, 0, + "0 %lu %lu\n", subgid->id, subgid->length); + } else { + r = pakfire_file_write(jail->pakfire, path, 0, 0, 0, + "0 %lu 1\n%1 %lu %lu\n", gid, subgid->id, subgid->length); + } - return pakfire_jail_write_uidgid_mapping(jail, path, subgid); + if (r) { + ERROR(jail->pakfire, "Could not map GIDs: %m\n"); + return r; + } + + return r; } static int pakfire_jail_setgroups(struct pakfire_jail* jail, pid_t pid) { @@ -1111,13 +1139,13 @@ static int pakfire_jail_wait_for_signal(struct pakfire_jail* jail, int fd) { static int pakfire_jail_parent(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) { int r; - // Write "deny" to /proc/PID/setgroups - r = pakfire_jail_setgroups(jail, ctx->pid); + // Setup UID mapping + r = pakfire_jail_setup_uid_mapping(jail, ctx->pid); if (r) return r; - // Setup UID mapping - r = pakfire_jail_setup_uid_mapping(jail, ctx->pid); + // Write "deny" to /proc/PID/setgroups + r = pakfire_jail_setgroups(jail, ctx->pid); if (r) return r; -- 2.39.5