diff --git a/NEWS b/NEWS index 1dfefd3c0d..ab6e61a1e4 100644 --- a/NEWS +++ b/NEWS @@ -12,18 +12,39 @@ CHANGES WITH 251: * Services with Restart=always and a failing ExecCondition= will no longer be restarted, to bring ExecCondition= in line with Condition*= settings. - * In v250 systemd-homed started making use of UID mapped mounts for the - home areas if the kernel and used file system support it. Files are - now internally owned by the "nobody" user (i.e. the user typically - used for indicating "this ownership is not mapped"), and dynamically - mapped to the UID used locally on the system via the UID mapping - mount logic of recent kernels. - In the current implementation systemd-homed only maps a limited - number of UIDs and GIDs making it impossible to run unprivileged - containers that want to map a full POSIX compliant UID and GID range - with their rootfs located within the systemd-homed managed home area. - This will be fixed in subsequent releases. See - https://github.com/systemd/systemd/pull/22239 for a proposal. + * Starting with v250 systemd-homed uses UID/GID mapping on the mounts + of activated home directories it manages (if the kernel and selected + file systems support it). So far it mapped three UID ranges: the + range from 0…60000, the user's own UID, and the range 60514…65534, + leaving everything else unmapped (in other words, the 16bit UID range + is mapped almost fully, with the exception of the UID subrange used + for systemd-homed users, with one exception from that: the user's own + UID). Unmapped UIDs may not be used for file ownership in the home + dirctory — any chown() attempts with them will fail. With this + release a fourth range is added to these mappings: + 524288…1879048191. This range is the UID range intended for container + uses, see: + + https://systemd.io/UIDS-GIDS + + This range may be used for container managers that place container OS + trees in the home directory (which is a questionable approach, for + quota, permission, SUID handling and network file system + compatibility reasons, but nonetheless apparently commonplace). Note + that this mapping is mapped 1:1 in a pass-through fashion, i.e. the + UID assignments from the range are not managed or mapped by + `systemd-homed`, and must be managed with other mechanisms, in the + context of the local system. + + Typically, a better approach to user namespacing in relevant + container managers would be to leave container OS trees on disk at + UID offset 0, but then map them to a dynamically allocated runtime + UID range via another UID mount map at container invocation + time. That way user namespace UID ranges become strictly a runtime + concept, and do not leak into persistent file systems, persistent + user databases or persistent configuration, thus greatly simplifying + handling, and improving compatibility with home directories intended + to be portable like the ones managed by systemd-homed. CHANGES WITH 250: diff --git a/docs/UIDS-GIDS.md b/docs/UIDS-GIDS.md index 5c05bf11cb..6931536185 100644 --- a/docs/UIDS-GIDS.md +++ b/docs/UIDS-GIDS.md @@ -233,6 +233,27 @@ safely use the NSS user database as allocation check, too. Note that if you follow this scheme no changes to `/etc/passwd` need to be made, thus minimizing the artifacts the container manager persistently leaves in the system. +5. `systemd-homed` by default mounts the home directories it manages with UID +mapping applied. It will map four UID ranges into that uidmap, and leave +everything else unmapped: the range from 0…60000, the user's own UID, the range +60514…65534, and the container range 524288…1879048191. This means +files/directories in home directories managed by `systemd-homed` cannot be +owned by UIDs/GIDs outside of these four ranges (attempts to `chown()` files to +UIDs outside of these ranges will fail). Thus, if container trees are to be +placed within a home directory managed by `systemd-homed` they should take +these ranges into consideration and either place the trees at base UID 0 (and +then map them to a higher UID range for use in user namespacing via another +level of UID mapped mounts, at *runtime*) or at a base UID from the container +UID range. That said, placing container trees (and in fact any +files/directories not owned by the home directory's user) in home directories +is generally a questionable idea (regardless of whether `systemd-homed` is used +or not), given this typically breaks quota assumptions, makes it impossible for +users to properly manage all files in their own home directory due to +permission problems, introduces security issues around SETUID and severely +restricts compatibility with networked home directories. Typically, it's a much +better idea to place container images outside of the home directory, +i.e. somewhere below `/var/` or similar. + ## Summary | UID/GID | Purpose | Defined By | Listed in | diff --git a/src/home/homework-mount.c b/src/home/homework-mount.c index 0b028dad37..35645e292e 100644 --- a/src/home/homework-mount.c +++ b/src/home/homework-mount.c @@ -209,6 +209,13 @@ static int make_userns(uid_t stored_uid, uid_t exposed_uid) { if (r < 0) return log_oom(); + /* Also map the container range. People can use that to place containers owned by high UIDs in their + * home directories if they really want. We won't manage this UID range for them but pass it through + * 1:1, and it will lose its meaning once migrated between hosts. */ + r = append_identity_range(&text, CONTAINER_UID_BASE_MIN, CONTAINER_UID_BASE_MAX+1, stored_uid); + if (r < 0) + return log_oom(); + /* Leave everything else unmapped, starting from UID_NOBODY itself. Specifically, this means the * whole space outside of 16bit remains unmapped */