]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Perform UID/GID setup for new namespace
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 10:50:41 +0000 (10:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 10:50:41 +0000 (10:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/jail.c

index b65f2bda66be05be0f3ef0048e16c759d9ab393c..e4b4798d284d85f194a926b65399dbb5f23a66b7 100644 (file)
@@ -218,6 +218,91 @@ int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char*
        return 0;
 }
 
+// UID/GID Mapping
+
+static int pakfire_jail_write_uidgid_mapping(struct pakfire_jail* jail,
+               const char* path, uid_t mapped_id, size_t length) {
+       int r = 1;
+
+       // Open file for writing
+       FILE* f = fopen(path, "w");
+       if (!f) {
+               ERROR(jail->pakfire, "Could not open %s for writing: %m\n", path);
+               goto ERROR;
+       }
+
+       // Write configuration
+       int bytes_written = fprintf(f, "%d %d %ld\n", 0, mapped_id, length);
+       if (bytes_written < 0) {
+               ERROR(jail->pakfire, "Could not write UID/GID mapping: %m\n");
+               goto ERROR;
+       }
+
+       // Success
+       r = 0;
+
+ERROR:
+       if (f)
+               fclose(f);
+
+       return r;
+}
+
+static int pakfire_jail_setup_uid_mapping(struct pakfire_jail* jail, pid_t pid) {
+       char path[PATH_MAX];
+       int r;
+
+       // XXX hard-coded values
+       const uid_t mapped_uid = 100000;
+       const size_t length = 64536;
+
+       // Make path
+       r = pakfire_string_format(path, "/proc/%d/uid_map", pid);
+       if (r < 0)
+               return 1;
+
+       DEBUG(jail->pakfire, "Mapping UID range (%u - %lu)\n", mapped_uid, mapped_uid + length);
+
+       return pakfire_jail_write_uidgid_mapping(jail, path, mapped_uid, length);
+}
+
+static int pakfire_jail_setup_gid_mapping(struct pakfire_jail* jail, pid_t pid) {
+       char path[PATH_MAX];
+       int r;
+
+       // XXX hard-coded values
+       const uid_t mapped_gid = 100000;
+       const size_t length = 64536;
+
+       // Make path
+       r = pakfire_string_format(path, "/proc/%d/gid_map", pid);
+       if (r < 0)
+               return 1;
+
+       DEBUG(jail->pakfire, "Mapping GID range (%u - %lu)\n", mapped_gid, mapped_gid + length);
+
+       return pakfire_jail_write_uidgid_mapping(jail, path, mapped_gid, length);
+}
+
+/*
+       Performs the initialisation that needs to happen in the parent part
+*/
+static int pakfire_jail_parent(struct pakfire_jail* jail, pid_t pid) {
+       int r;
+
+       // Setup UID mapping
+       r = pakfire_jail_setup_uid_mapping(jail, pid);
+       if (r)
+               return r;
+
+       // Setup GID mapping
+       r = pakfire_jail_setup_gid_mapping(jail, pid);
+       if (r)
+               return r;
+
+       return 0;
+}
+
 static int pakfire_jail_child(struct pakfire_jail* jail, const char* argv[]) {
        // XXX do we have to reconfigure logging here?
 
@@ -256,6 +341,11 @@ int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) {
                _exit(r);
        }
 
+       // Parent process
+       r = pakfire_jail_parent(jail, pid);
+       if (r)
+               goto ERROR;
+
        // Set some useful error code
        int exit;
        int status = 0;
@@ -277,4 +367,8 @@ int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) {
        }
 
        return exit;
+
+ERROR:
+
+       return -1;
 }