|
|
Subscribe / Log in / New account

Addressing UID/GID drift in rpm-ostree and bootc

By Joe Brockmeier
April 23, 2025

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.



to post comments

Ubuntu Core explored this topic as well

Posted Apr 23, 2025 17:17 UTC (Wed) by zyga (subscriber, #81533) [Link]

Ubuntu Core, a special flavour of Ubuntu based on immutable squashfs filesystems explored this as well. Quite a bit of discussion and analysis is still on the Snapcraft forum, in this thread: https://forum.snapcraft.io/t/multiple-users-and-groups-in...

The notes are from 2017 but a lot of the observations remain valid to this day.

what does suse/Ubuntu do different?

Posted Apr 23, 2025 17:25 UTC (Wed) by rcampos (subscriber, #59737) [Link] (3 responses)

I wonder what Ubuntu and suse do different in their immutable versions to avoid this issue.

Does anyone know?

what does suse/Ubuntu do different?

Posted Apr 23, 2025 18:36 UTC (Wed) by zyga (subscriber, #81533) [Link]

I cannot speak for SUSE but Ubuntu Core experiences this problem in two different ways:

Ordinary application squashfs cannot use users or groups ot eh we than root. This is sometimes problematic and requires patching applications to compensate. The reason for this is that one cannot allocate such IDs at runtime and some mimetic value must be baked into the signed disk image.

The second problem is that the same base squashfs snap is used on Ubuntu Core distribution, classic Ubuntu, Debian, Fedora and any other. In all the cases the user and group database is provided by the host and, outside of core itself, may not line up exactly as one would want.

what does suse/Ubuntu do different?

Posted Apr 24, 2025 6:24 UTC (Thu) by danieldk (subscriber, #27876) [Link]

OSTree/bootc build an image. Every update is basically a fresh image with the packages installed from scratch into the image, which leads to the ordering issue. As far as I understand with the SUSE atomic versions they use traditional system updates combined with btrfs snapshots. So when an update is done, a new snapshot is made, the snapshot is mounted read-write and various directories are mounted on top of it. Then the read-write snapshot is updated using Zypper as a normal, mutable SUSE system. If the update failed, the snapshot is discarded. If the update was successful, the snapshot is unmounted and then mounted as the read-only root during the next boot. It doesn't have the UID/GID issue, because aside from the tricks to make root read-only, it updates in the same way is a non-atomic Linux system.

Disclaimer: I don't use SUSE, this is what I found based on the documentation.

what does suse/Ubuntu do different?

Posted Apr 25, 2025 8:00 UTC (Fri) by kukuk (subscriber, #39885) [Link]

> I wonder what Ubuntu and suse do different in their immutable versions to avoid this issue.

SUSE does not ship /etc/passwd or /etc/group but generate that at install time, we do that at least for MicroOS and derivatives, and add new users via sysusers.d at update time.

The /etc directory of most Linux distributions contains four kind of files:
* host specific files generated at install time or first boot, like /etc/machine-id, /etc/passwd, /etc/group, ...
* distribution provided configuration files, which admins and distributors can change
* admin made changes
* stuff which does not belong to /etc, but where upstream projects are reluctant to fix that. Why do we need shell scripts for grub in /etc?

If you update that with a package manager, the package manager will try to merge that for you. If you have an image based system, that's not possible. That's why I don't understand why some image based distributions could come to the idea to ship /etc with their image. It's a big mess if you update the image.

The mid- to long term plan for SUSE is to have a hermetic-usr system. For many core package we have that already, but it's still a long way to go, especially as many upstream projects are not interested in this and reject patches.
But that's the only clean solution for the current /etc mess in update case, even for traditional distributions.

Tough problem

Posted Apr 23, 2025 18:23 UTC (Wed) by dbnichol (subscriber, #39622) [Link] (1 responses)

Endless OS is based on ostree like this. We've avoided this there by nss-altfiles with static passwd and group files in /lib containing every possible user and group with fixed IDs. It's ugly, all the developers hate it, and it only works because Endless doesn't allow system overlays like rpm-ostree does. Our ostree build process is also a little simplified compared to rpm-ostree in that we install Debian packages in a root, let them run the maintainer scripts as they want, and then do any necessary cleanup before the commit.

We really would have preferred to make this semi-dynamic using systemd-sysusers. What I thought was the only reasonable solution was to finalize the passwd and group files during the ostree build process. I think this is basically the soft-static proposal + sysusers but without negotiations. Essentially:

1. After the ostree is completely assembled, parse /etc/passwd and /etc/group to find any users and groups defined by the build.
2. Parse all the conf files in /usr/lib/sysusers.d to find any users and groups defined by that method.
3. Verify that any non-root user or group has an accompanying sysusers entry.
4. Walk the entire assembled tree looking for paths that are not owned by root. Note that /var is deleted at this point, which is one of the main sources of non-root owned files. Verify that any non-root owned path has a fixed ID in its sysusers entry.
5. Truncate the user/group DBs (/etc/{passwd,shadow,group,gshadow}) so they just contain the root entry. We have verified that any other required user or group will be created by systemd-sysusers at runtime.

At runtime systemd-sysusers fills in the users and groups, and some of them will have fixed IDs per the above process. This is idealistic, though, as it does nothing to address systems that have already allocated a user or group and the existing ID doesn't match the fixed ID in the sysusers entry. In other words, the drift discussed here. Also, I never actually got around to implementing it.

Tough problem

Posted Apr 24, 2025 14:30 UTC (Thu) by MrWim (subscriber, #47432) [Link]

It probably wouldn't be that hard to modify ostree's checkout logic to map UIDs and GIDs when doing a checkout. For /usr you'd still require everything to be root:root, which would be necessary for the hard-linking it does, but for /etc it has to copy anyway, so there wouldn't be any issues.

You'd map the ostree's UIDs and GIDs to usernames/group names according to /etc/passwd and /etc/group inside the ostree tree, and then map back again according to the host's /etc/passwd and /etc/group.

Obviously it's still better to avoid that complexity if you can.

idmapped mounts

Posted Apr 24, 2025 1:04 UTC (Thu) by geofft (subscriber, #59789) [Link] (20 responses)

It seems like ID-mapped mounts (https://lwn.net/Articles/896255/, https://github.com/brauner/mount-idmapped) would address this use case, at the cost of a tiny bit of kernel overhead.

Specifically, it seems like the most underlying problem is that filesystems store UIDs and GIDs, not user and group names (or some other larger namespace that more precisely identifies the semantics of ownership; you could imagine UUIDs or URIs or something even wackier, as long as it's not small integers from a range of a couple hundred). If you could store the names directly the problem wouldn't arise.

So, you store files with numbers, as you have to, but at the root of the filesystem in question (the /etc or /var partition), make a file that records what the meaning of the UIDs and GIDs used on this filesystem are. This could be literally in the format of the passwd and group files, stored as /.fspasswd and /.fsgroup or something. (These files themselves should be owned by, say, UID/GID 0, along with a convention that 0 always maps to root and is never remapped, since presumably root is not going to drift.)

Then, when you mount the filesystem, first mount it in a temporary location. Read in the /mnt/.fspasswd and /mnt/.fsgroup files, and compare them with /etc/passwd and /etc/group (or more precisely NSS output) on the running system. If there are discrepancies, construct an ID-mapping to fix them, such as "gid:999:998:1" for the example in the article (if I have the direction right). If there are any relevant accounts (probably just accounts managed by sysusers) that are not present in the .fspasswd and .fsgroup files, add them. Then create an idmapped mount in the right place and unmount the temporary mount.

This way, the filesystem stores, inside itself, the actual meaning of all the UIDs and GIDs in use on that filesystem, so in effect you can treat the filesystem as if it stored files with user and group names instead of numeric IDs. This is compatible with other approaches to try to address drift, in that obviously things are simpler if there is no idmap, but it does address drift when it happens. Would this be workable for Fedora?

idmapped mounts

Posted Apr 24, 2025 2:18 UTC (Thu) by champtar (subscriber, #128673) [Link]

> since presumably root is not going to drift.

Make me think of this bug https://issues.redhat.com/browse/RHEL-72572 where systemd-sysusers creates root group (in the initramfs) with GID 999 :)

idmapped mounts

Posted Apr 24, 2025 4:08 UTC (Thu) by NYKevin (subscriber, #129325) [Link] (11 responses)

Overall, that sounds like a perfectly reasonable approach, but I can think of one minor-but-possibly-annoying corner case: What happens if a package renames its system user?

In the "old world" (fs stores numbers, names are mostly decorative), this either causes a minor cosmetic issue where ls output and the like still uses the old name, or else the package manager updates /etc/passwd with the new name and everything Just Works. As such, developers are likely to assume that this is a reasonably safe thing to do, even if a package has already been widely deployed and regularly owns a ton of files.

In the "new world" (fs stores both numbers and a name-number mapping), this becomes a bit of a mess. Since we're recreating the image from scratch, we're going to end up with the new names in /etc/passwd, whether we want them or not. The old names will still be in the filesystem root mapping, because the whole point of said mapping is to remain stable even when the image is rebuilt. It's a question of whether your UID remapping logic is smart enough to do an automated migration at the next opportunity, or if it just fails to map the old names to the new UIDs.

idmapped mounts

Posted Apr 24, 2025 19:32 UTC (Thu) by geofft (subscriber, #59789) [Link] (1 responses)

Is the package able to retain the former names of the system users? If you have that available in some form of metadata, then you can easily update the .fspasswd file to the current canonical name as part of the process of matching up its accounts to the current system's accounts. I would assume that, for non-image-based systems, the package's pre/post scriptlets need to rename the user anyway, so that information is already included in the package in some form.

I guess one problem is that sysusers files do not even have a spot for extensible metadata.

idmapped mounts

Posted Apr 28, 2025 2:27 UTC (Mon) by NYKevin (subscriber, #129325) [Link]

I'm sure the data needed to do this exists in some form. My question was mostly centered on:

* Whether the data is readily available at the appropriate time (i.e. everything is mounted or about to be mounted and we can actually do a UID/username migration right now).
* Whether the tooling is smart enough to do it automatically, or if that functionality still needs to be built out.

idmapped mounts

Posted Apr 24, 2025 20:08 UTC (Thu) by mathstuf (subscriber, #69389) [Link]

I may have been playing with fire at the time, but you can have two users that share a uid in `/etc/passwd`. I did it to shove Steam into a different `$HOME` before flatpak was a thing to avoid it dumping things into there (IIRC, trying to use symlinks to move where it actually did stuff broke things at the time).

idmapped mounts

Posted Apr 25, 2025 4:51 UTC (Fri) by DemiMarie (subscriber, #164188) [Link] (7 responses)

I think the best solution is to use something like GUIDs or Windows’s SIDs.

idmapped mounts

Posted Apr 25, 2025 11:40 UTC (Fri) by SLi (subscriber, #53131) [Link] (2 responses)

Yeah, it would make sense to have a single thing that nobody has any reason to ever change, an "identity", which is a UUID. All other things like the username should be just properties attached to this. Perhaps even the transient things like uid.

idmapped mounts

Posted Apr 25, 2025 14:18 UTC (Fri) by intelfx (subscriber, #130118) [Link] (1 responses)

Yup.

I was practically screaming "UUIDs" (or, hell, SIDs) at the screen the entire time I was reading the article and the comments. But that would be too sane. So we're stuck with hacks on top of hacks on top of hacks on top of hacks.

User UUIDs

Posted Apr 25, 2025 17:09 UTC (Fri) by DemiMarie (subscriber, #164188) [Link]

Those would allow idmapped users to work in a decent way.

idmapped mounts

Posted Apr 25, 2025 17:41 UTC (Fri) by geofft (subscriber, #59789) [Link] (3 responses)

I was surprised to find that Windows SIDs are arbitrary-length. I suppose the NT kernel is designed sufficiently differently from UNIX that they don't have the same model of numeric user IDs and access checks are performed with tokens/handles, so you can put the SID behind a pointer and deal with the indirection and memory allocation rarely. But it feels like this has to be high-overhead for file access checks on NTFS files, which store ownership by SID.

I was also surprised to find that, even with SIDs, Active Directory accounts also have a GUID, and SIDs can change but GUIDs are permanent. There is an "SIDHistory" field in the AD object that lists all previous SIDs of the account. https://learn.microsoft.com/en-us/windows-server/identity...

I was amused but not actually surprised to find that NTFS-3G Linux driver supports mapping SIDs to UIDs/GIDs via a text file in a hidden directory in the filesystem root. :) https://github.com/tuxera/ntfs-3g/wiki/File-Ownership-and...

idmapped mounts

Posted Apr 28, 2025 2:16 UTC (Mon) by NYKevin (subscriber, #129325) [Link] (2 responses)

> I suppose the NT kernel is designed sufficiently differently from UNIX that they don't have the same model of numeric user IDs and access checks are performed with tokens/handles, so you can put the SID behind a pointer and deal with the indirection and memory allocation rarely. But it feels like this has to be high-overhead for file access checks on NTFS files, which store ownership by SID.

To the best of my understanding, the Microsoft answer to that problem is "don't pervasively hang permissions on every single object in the entire filesystem." Instead, permissions are inherited from the parent directory by default (and from its parent recursively, all the way up to the root or until you hit a directory with non-inherited permissions). So you don't have to do N checks for a path consisting of N components - you just do one or two checks for the high-level directories that actually have permissions on them, and everything else is cheap lookups of cached ACLs.

> I was also surprised to find that, even with SIDs, Active Directory accounts also have a GUID, and SIDs can change but GUIDs are permanent.

As a rule of thumb, in the Microsoft universe, everything has a GUID, or else it must not be very important.

idmapped mounts

Posted May 2, 2025 17:19 UTC (Fri) by Conan_Kudo (subscriber, #103240) [Link] (1 responses)

Yep. And personally, I think it's a smarter model.

idmapped mounts

Posted May 3, 2025 8:44 UTC (Sat) by Wol (subscriber, #4433) [Link]

The problem is that - in the standard Unix filesystem model - we have a flat root-level namespace. All files are uniquely identified by their i-node.

The directory system is independent (which is what gives us hard links). So the mechanism that works everywhere else - "traverse back up the file tree until you hit an ACL" - doesn't work in Posix.

Cheers,
Wol

idmapped mounts

Posted Apr 24, 2025 10:26 UTC (Thu) by taladar (subscriber, #68407) [Link] (1 responses)

It might be necessary to consider the security implications here, especially in combination with files getting privileges related to their owner/group (setuid is one example but there might be others). At the very least you probably want to avoid mounting removable media with this type of mapping and without the noexec mount option at the same time.

idmapped mounts

Posted Apr 24, 2025 19:42 UTC (Thu) by geofft (subscriber, #59789) [Link]

I was originally going to say that this mechanism should only be used for trusted filesystems like /etc or /var (where being able to make a file with name and contents of your choice lets you pwn the system, even without particular control of that file's ownership). But thinking about this more, I do not think that remapping UIDs increases the danger of untrusted filesystems. An untrusted filesystem can already make whatever claims about UIDs and file permissions that it wants, i.e., it can contain setuid binaries for any possible UID. Giving it the ability to target a specific user account by name isn't actually giving it more power. It's maybe making an attack logistically easier, but notably it doesn't make things easier for attacking root, which is always UID 0, or any other accounts with fixed UIDs. (An attacker can also just have a directory with setuid binaries for every possible UID, and a launcher that looks up the account it wants to target and picks the right setuid binary.)

You probably want to mount removable media nosuid and perhaps noexec and nodev unless explicitly told otherwise by the user, regardless of whether you are remapping UIDs on the filesystem.

idmapped mounts

Posted Apr 24, 2025 18:20 UTC (Thu) by Wol (subscriber, #4433) [Link] (1 responses)

> Specifically, it seems like the most underlying problem is that filesystems store UIDs and GIDs, not user and group names (or some other larger namespace that more precisely identifies the semantics of ownership; you could imagine UUIDs or URIs or something even wackier, as long as it's not small integers from a range of a couple hundred). If you could store the names directly the problem wouldn't arise.

At which point, any sane dba will have his head in his hands, weeping and crying "when will they learn?!". NAMES ARE A DAFT IDEA!

Names are not unique. Names change. Names screw you over. Real case study, a friend of mine wrote a medical database keyed on surname ... at which point I got involved. And gently pointed out that a lady doctor getting married would corrupt the database. A new doctor joining with the same surname would corrupt the database. Etc etc.

It's normal practice to reserve some space for system uids/gids - under 500, or under 1000. The obvious solution (yes I know, "simple, obvious, and wrong") would be to reserve the top - lets say 200 - of those entries and pre-allocate them. Okay, we run the risk of running out of pre-allocations, but at least that's a problem we can catch at build time, not when an image goes live and screws the user over.

I'm all for real-world primary keys, I'd much rather use an SSN or NI number or VIN number than some random uid that changes between databases, but as soon as we get into this problem space, we need a primary key that uniquely identifies the item of interest. And names AREN'T IT. Sendmail, anyone?

Cheers,
Wol

idmapped mounts

Posted Apr 24, 2025 19:24 UTC (Thu) by geofft (subscriber, #59789) [Link]

Well, these are usernames, not names in the human sense. We already have the problem that usernames are hard to change. Plenty of other things on the system will reference accounts by username instead of by UID - home directory, sudo rules, /etc/shadow, PAM, etc. etc. Correctly and fully changing the username of an account on an existing traditional-UNIX system is a problem that's as hard as changing the UID.

(I actually wonder what a good solution to this would be in the general case. In practice, if you have an employee who has changed their name and whose username represents their old name, the most reliable solution seems to be to give them an entirely new user account, grant them continued access to the old one, and ask them to migrate things as they go. And heavens help you if you are sysadminning a merger between two companies with traditional UNIX account systems like LDAP; username conflicts are just as much of a pain as user ID conflicts.)

But yes, that's why I mentioned UUIDs or URIs in the sentence you quoted, which avoid the problems you describe. You need a way to associate the UID/GID on the filesystem with a persistent, unambiguous identifier for an account; you can then figure out what username and UID that account has on the current running system, both of which could have changed since the files were written, and you can handle them both correctly.

My guess is that the entire reason Fedora is having this discussion is that there are not, in fact, enough UIDs in the <1000 range for every use case in Fedora for a system user to pre-allocate one. This is the "soft-static assignment" approach proposed in the article; the link takes you to a sentence that explains that a ticket is needed precisely because the available space is limited.

idmapped mounts

Posted Apr 24, 2025 20:04 UTC (Thu) by mathstuf (subscriber, #69389) [Link] (2 responses)

Alternatively, could the intended uname/gname be stored as xattrs? Then scan `/etc` for non-root files, check that the names and uid/gid match and if not, look up the new ids and update them directly. Would also work for rollbacks, no?

idmapped mounts

Posted Apr 24, 2025 21:32 UTC (Thu) by geofft (subscriber, #59789) [Link] (1 responses)

The complication with that approach is you need something to store the xattr on every file creation and update it on every chown; your average program that creates a config file or a state file won't have logic to do this, so you'll end up with a file with a non-root UID and no xattr explaining what that UID means. (Creating the file in advance isn't always an option - consider things like log rotation where the program renames the old file and creates a new one.) ID-mapping is a feature that's already in the kernel that takes place in the path between the program creating a file and the bits ending up on disk, so if you set up the ID map, then any unmodified userspace program using the mount gets the right behavior behind the scenes.

I guess you could teach the kernel to create these xattrs. Maybe an LSM can do it? Or maybe you could make a FUSE filesystem that does it, though overhead is likely unacceptably high.

idmapped mounts

Posted Apr 25, 2025 6:50 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

Ah right… Perhaps it could be a periodic process that goes and adds the xattr to any files missing them in `/etc` and `/var` (and some tool to detect missed xattrs on startup)?

Static passwd/group + checks

Posted Apr 24, 2025 2:24 UTC (Thu) by champtar (subscriber, #128673) [Link]

At work we use rpm-ostree but rarely overlay anything that we don't control,
so we ended up having static passwd/group + the following in postprocess-script:

> systemd-sysusers
> # fail if extra user / group have been created
> tail -n1 /etc/passwd | grep -q nobody || exit 42
> tail -n1 /etc/group | grep -q nobody || exit 42

NixOS also deals with that

Posted Apr 24, 2025 6:44 UTC (Thu) by spacefrogg (subscriber, #119608) [Link] (3 responses)

Being an image-based distribution in that particular regard, NixOS also has to take care of UID drift. There, the OS maintains a passwd/groups database in /var, such that a UID/GID once created is not changed later in a particular installation, even if the configuration demands it. On each system update the admin gets notified about the UID/GID mismatch such that they can clean up.

NixOS also deals with that

Posted Apr 24, 2025 13:50 UTC (Thu) by mattdm (subscriber, #18) [Link] (1 responses)

> On each system update the admin gets notified about the UID/GID mismatch such that they can clean up.

This is not a viable approach for a general-purpose distribution like Fedora Linux.

NixOS also deals with that

Posted Apr 25, 2025 5:47 UTC (Fri) by rgb (subscriber, #57129) [Link]

But this UID/GID mismatch is exactly what you want? It is just a missmatch between the current system and the package spec. There are only two options (if you don't want to re-assign every file in /home etc):

1) spec matches /usr; missmatch between /usr and /home
2) /usr matches /home; missmatch between /usr and spec

NixOS also deals with that

Posted Apr 25, 2025 5:29 UTC (Fri) by rgb (subscriber, #57129) [Link]

> even if the configuration demands it

Do you have an example when this might happen? I can only think of a package that switches from dynamic to static user/group creation on update, but that should be very rare?

Allocate uids based on username?

Posted Apr 25, 2025 13:27 UTC (Fri) by alexl (subscriber, #19068) [Link] (1 responses)

Can we maybe allocate dynamic uid:s not sequentially, but based on the user name. Pick a large range, say 24bits (with the upper 8 bits as a tag), and then use "hash(username) & 0xffffff" to allocate the id (handling conflicts like a hash table). This would make it quite unlikely to have conflicts.

This is like a micro-version of GUIDs, but without changing the format.

Allocate uids based on username?

Posted Apr 26, 2025 12:52 UTC (Sat) by smcv (subscriber, #53363) [Link]

If you want your OS to be runnable in a rootless container (like the typical use of Podman) then you can only rely on having a 16-bit range available (for everyone - system users as well as humans' user accounts), so there aren't really enough uids available for this sort of sparse allocation to avoid collisions reliably.

I think Debian is fairly typical here: it puts dynamically-allocated system users (the ones being discussed here) in the range 100-999, so there are only 900 available. (As per https://www.debian.org/doc/debian-policy/ch-opersys.html#... 90% of the 16-bit range is made available to sysadmins for local allocation of humans' user accounts.)

systemd-userdb

Posted Apr 28, 2025 6:02 UTC (Mon) by pothos (subscriber, #116075) [Link]

I think static assignment makes most sense for image based distros. With systemd-userdb a JSON record can be shipped as part of /usr and gets integrated with the system throught nss.
Ideally the package is the source of this but one can also generate it at image build time.


Copyright © 2025, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds