]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
jail: Try to be smarter when mapping UID/GIDs
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 31 Oct 2022 10:32:39 +0000 (10:32 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 31 Oct 2022 10:32:39 +0000 (10:32 +0000)
This still doesn't work any I have absolutely no idea why. It shouldn't
be a problem :(

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/jail.c

index 1de30827f025681c4a5d378292ff821dcf6cd15d..e0d48d685eb98c69c2dc9020042caff82ade2e7c 100644 (file)
@@ -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;