Addressing UID/GID drift in rpm-ostree and bootc
The Fedora Project is looking for solutions to an interesting problem with its image-based editions and spins, such as the Atomic Desktops or CoreOS, that are created with rpm-ostree or bootc. If a package that is part of a image-based version has a user or group created dynamically on installation, and it owns files installed on the system, the system may be subject to user ID (UID) and group ID (GID) "drift" on updates. This "UID/GID drift" may come about when a new image with updates is generated, and therefore files may have the wrong ownership. This can have side-effects ranging from mildly inconvenient to serious. No solutions have been adopted just yet, but there are a few ideas on how to deal with the problem.
UID/GID Drifting
In a traditional package-based install of Fedora Linux, a package would be installed once and upgraded thereafter. If part of its installation includes dynamically allocating a user and/or group, the UID and GID will be assigned once, and it should not be changed by upgrades to the package later on. However, things work differently for image-based versions of Fedora. Instead of installing packages once and then updating them as needed, the images created by rpm-ostree and bootc are generated from packages each time an update is created. (LWN covered rpm-ostree's underlying technology OSTree in 2014, and looked at bootc in 2024.)
Even though image-based distributions are often described as "immutable", that is not exactly the case. As the documentation for Fedora Silverblue explains, only some of the filesystem and directories are immutable or read-only. The /etc and /var directories store configuration files, runtime state, and data that is writable and persists between updates.
Most of the time UID and GID assignments will remain static between updates. As Zbigniew Jędrzejewski-Szmek pointed out on the fedora-devel mailing list when raising the UID/GID drift problem, as long as the list of packages remains the same, the installation order of the packages is stable and will always get the same UIDs/GIDs.
But we can get different assignments if the package installation order changes, for example because of some dependency change, or more/less packages are installed, or when one of the packages defines a new user/group. In general, we can expect the uid/gid assignments to change regularly.
He goes into detail using the opencryptoki package as an example. That package creates the pkcs11 group when installed, and its GID is selected at that time. The package has a file in its payload, /etc/opencryptoki/strength.conf, that is owned by the pkcs11 group. An rpm-ostree or bootc image is built that includes that package, and it receives the GID 999 (for example) from the range of GID numbers that are available to system accounts. Users deploy that image to their systems. The /etc/opencryptoki/strength.conf file is now owned by GID 999 because filesystems store ownership as numbers and not user or group names.
Later, when a new image is created from package updates, something changes in the package order. This means that the pkcs11 group gets GID 998 this time. Note that files in /etc (or /var) are not necessarily overwritten when there is a new image, so some of the files that have group ownership stored as GID 999, such as /etc/opencryptoki/strength.conf, may persist even though the pkcs11 group is now GID 998. So when users update to the new image, some files are owned by a GID that either maps to a different group in /etc/group or to no group at all.
The consequences of such wrong ownership can vary: in the most benign case this is just a cosmetic issue in 'ls' output. The case that is actually reported by users is when the service fails to start because it cannot access some file. But then there's also some silent group of cases where the wrong ownership creates a security vulnerability or an information leak.
Jędrzejewski-Szmek noted that the way that users and groups are created changed in Fedora 42. Instead of packages having scripts (referred to as "scriptlets") that call utilities like useradd and groupadd, the package should have a sysusers.d file which is processed by systemd-sysusers. The change proposal explains this in more detail. However, despite the change in mechanism in assigning users and groups, it does not have any impact on UID/GID drift. Users and groups are still assigned dynamically out of the same range of UID and GID numbers. There are currently 372 unique names for users or groups in the sysusers files for Fedora Rawhide, he said.
Fedora is the only major distribution using rpm-ostree and bootc to create image-based releases. The openSUSE Project uses Btrfs for its image-based versions such as Aeon and MicroOS. Ubuntu uses ubuntu-image to create its Ubuntu Core distribution. Those approaches do not seem to have have the UID/GID drift problem.
Proposed solutions
He suggests three possible solutions. The first approach, which he recommends, would be to simply not have any files owned by system users other than root. That would align with the "hermetic /usr" approach for immutable, image-based systems, as described by Lennart Poettering in a blog post from 2022:
In my model a hermetic OS is hence comprehensively defined within /usr/: combine the /usr/ tree with an empty, otherwise unpopulated root file system, and it will boot up successfully, automatically adding the strictly necessary files, and resources that are necessary to boot up.
Another approach would be to keep the files unowned—actually,
owned by the root user or group—as part of the package payload
but change ownership after installation by specifying the desired
ownership in tempfiles.d
configuration files. That avoids incorrect UID/GID assignments, but at
the cost of having to create and maintain the necessary tmpfiles.d
configuration. Jędrzejewski-Szmek noted that it can be
implemented easily, but "it's actually quite a bit of work and
bother to do correctly
".
The third option he proposed is soft-static
assignment of UIDs and GIDs. That requires packagers to file a
ticket with Fedora's packaging committee and justify the need for a
static assignment. In addition to the bureaucracy and additional work
for packagers, it would also create potential conflicts with
third-party packages. Jędrzejewski-Szmek mused that the project
could consider bigger changes, such as not using numeric UIDs/GIDs for
bootc images and only assigning those during installation. But he
offered no way to achieve that. He said that combining the first two approaches,
"minimizing the number of 'owned files' and judiciously using
tmpfiles.d to adjust ownership at runtime
", would be a relatively
painless option and called for comments or other ideas.
The creator of rpm-ostree and bootc, Colin Walters, replied
that there was a proposal for
bootc to automatically reset file ownership in the event of UID/GID
drift that he hoped to put on the near-term roadmap. He said that it
would take bootc a bit away from being image-based "but only
slightly and would greatly help the problem
".
Neal Gompa did not like the idea of ownerless files or having to fiddle with tmpfiles to assign ownership. He complained that the project had just introduced support for sysusers to make things easier for packagers, and now it looked like things could become more complex than they were before.
I don't think that will fly, at least it doesn't with me.
Having packages create a user, pre-own directories and files, and install them with that ownership is a rather common pattern that is essentially unavoidable. I do not see a scalable solution to work around that.
Jędrzejewski-Szmek said that he used to think that way as well, but he had found other reasons to avoid owned files, such as using bootc to create system images as an unprivileged user. He also said that there were maybe one-hundred packages that needed to be changed, and that they could be changed if ownerless was the best approach.
At the moment, the project is still mulling its options, and there has not been an abundance of ideas or objections offered to date. UID/GID drift is a real, if infrequent, problem. I've been using various image-based Fedora versions off and on for more than a decade, and haven't run into it on any of my systems. But a problem doesn't need to be common to be worth solving.
It will be interesting to see what solution Fedora develops—and what new problems the solutions create. Sometimes one gets the impression that every time a problem is solved in distributing and installing open-source software, two more spring up hydra-like in its wake.
