// 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;
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) {
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)
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) {
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;