Fedora Account System
Red Hat Associate
Red Hat Customer
shadow-utils-4.18.0-5.fc44 was built for testing yesterday. In openQA testing, user account creation in gnome-initial-setup failed on Silverblue (but worked on Workstation). The journal messages indicate an SELinux issue: Nov 26 08:46:00 fedora accounts-daemon[952]: request by system-bus-name::1.71 [/usr/libexec/gnome-initial-setup pid:2415 uid:60578]: create user '(username)' Nov 26 08:46:00 fedora chronyd[909]: Selected source 216.197.228.230 (2.fedora.pool.ntp.org) Nov 26 08:46:00 fedora audit[2731]: AVC avc: denied { read write } for pid=2731 comm="useradd" name="shadow" dev="vda3" ino=121940 scontext=system_u:system_r:useradd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=0 Nov 26 08:46:00 fedora accounts-daemon[2731]: useradd: cannot open /etc/shadow Nov 26 08:46:00 fedora useradd[2731]: failed adding user '(username)', exit code: 1 Nov 26 08:46:00 fedora gnome-initial-setup[2415]: Error saving data: Failed to create user '(username)': GDBus.Error:org.freedesktop.Accounts.Error.Failed: running '/usr/sbin/useradd' failed: Child process exited with code 1 I rebooted my VM with enforcing=0 and user account creation succeeded this time. ausearch shows a lot of AVCs for /etc/shadow: time->Wed Nov 26 08:50:38 2025 type=AVC msg=audit(1764175838.668:93): avc: denied { read } for pid=903 comm="accounts-daemon" name="shadow" dev="vda3" ino=121940 scontext=system_u:system_r:accountsd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:38 2025 type=AVC msg=audit(1764175838.668:94): avc: denied { open } for pid=903 comm="accounts-daemon" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:accountsd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:38 2025 type=AVC msg=audit(1764175838.668:95): avc: denied { getattr } for pid=903 comm="accounts-daemon" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:accountsd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:39 2025 type=AVC msg=audit(1764175839.532:126): avc: denied { read } for pid=1108 comm="unix_chkpwd" name="shadow" dev="vda3" ino=121940 scontext=system_u:system_r:chkpwd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:39 2025 type=AVC msg=audit(1764175839.532:127): avc: denied { open } for pid=1108 comm="unix_chkpwd" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:chkpwd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:39 2025 type=AVC msg=audit(1764175839.532:128): avc: denied { getattr } for pid=1108 comm="unix_chkpwd" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:chkpwd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:40 2025 type=AVC msg=audit(1764175840.658:141): avc: denied { read } for pid=903 comm="accounts-daemon" name="shadow" dev="vda3" ino=121940 scontext=system_u:system_r:accountsd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:40 2025 type=AVC msg=audit(1764175840.658:142): avc: denied { open } for pid=903 comm="accounts-daemon" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:accountsd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:50:40 2025 type=AVC msg=audit(1764175840.658:143): avc: denied { getattr } for pid=903 comm="accounts-daemon" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:accountsd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:51:07 2025 type=AVC msg=audit(1764175867.934:161): avc: denied { read write } for pid=2377 comm="useradd" name="shadow" dev="vda3" ino=121940 scontext=system_u:system_r:useradd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:51:07 2025 type=AVC msg=audit(1764175867.934:162): avc: denied { open } for pid=2377 comm="useradd" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:useradd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:51:07 2025 type=AVC msg=audit(1764175867.934:163): avc: denied { getattr } for pid=2377 comm="useradd" path="/etc/shadow" dev="vda3" ino=121940 scontext=system_u:system_r:useradd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 ---- time->Wed Nov 26 08:51:07 2025 type=AVC msg=audit(1764175867.945:164): avc: denied { unlink } for pid=2377 comm="useradd" name="shadow" dev="vda3" ino=121940 scontext=system_u:system_r:useradd_t:s0 tcontext=system_u:object_r:getty_etc_t:s0 tclass=file permissive=1 It's odd that it's showing the tcontext as system_u:object_r:getty_etc_t:s0 but when I do ls -Z /etc/shadow it says it's system_u:object_r:shadow_t:s0 . Not sure what's going on there. For now we have rolled back the changes in a shadow-utils-4.18.0-7.fc44 , but ipedrosa (the maintainer) would like to be able to make the changes from -4 and -5 eventually, I think.
Full path is not recorded, but the shadow file's label is incorrect whatever path it is. It also means the problem is when the file is created, I don't know if it is in shadow-utils or g-i-s, or it is in how silverblue works. I can't see a way how to fix anything in selinux-policy now.
I checked every file I could find called 'shadow' and they all had the system_u:object_r:shadow_t:s0 context... root@fedora:/# find -name shadow ./etc/shadow find: ‘./proc/1084/task/1084/net’: Invalid argument find: ‘./proc/1084/net’: Invalid argument find: ‘./run/user/1000/doc’: Permission denied find: ‘./run/user/1000/gvfs’: Permission denied ./sysroot/ostree/deploy/fedora/deploy/d5c9e078683a5cf0fdbac26bd2f8dfedaadb7f663af3763a5e99f4733fab4c4f.0/usr/etc/shadow ./sysroot/ostree/deploy/fedora/deploy/d5c9e078683a5cf0fdbac26bd2f8dfedaadb7f663af3763a5e99f4733fab4c4f.0/etc/shadow ./usr/etc/shadow ./var/lib/flatpak/runtime/org.fedoraproject.Platform/x86_64/f43/b7c550ffaabbcf07e6552e9679f18ca6bacc755d4002f6b49b980c561c5f1001/files/etc/shadow root@fedora:/# ls -Z ./sysroot/ostree/deploy/fedora/deploy/d5c9e078683a5cf0fdbac26bd2f8dfedaadb7f663af3763a5e99f4733fab4c4f.0/usr/etc/shadow system_u:object_r:shadow_t:s0 ./sysroot/ostree/deploy/fedora/deploy/d5c9e078683a5cf0fdbac26bd2f8dfedaadb7f663af3763a5e99f4733fab4c4f.0/usr/etc/shadow root@fedora:/# ls -Z ./sysroot/ostree/deploy/fedora/deploy/d5c9e078683a5cf0fdbac26bd2f8dfedaadb7f663af3763a5e99f4733fab4c4f.0/etc/shadow system_u:object_r:shadow_t:s0 ./sysroot/ostree/deploy/fedora/deploy/d5c9e078683a5cf0fdbac26bd2f8dfedaadb7f663af3763a5e99f4733fab4c4f.0/etc/shadow root@fedora:/# ls -Z ./usr/etc/shadow system_u:object_r:shadow_t:s0 ./usr/etc/shadow
OK, the path is here: Nov 26 08:46:00 fedora accounts-daemon[2731]: useradd: cannot open /etc/shadow The getty_etc_t type is assigned to /etc/mgetty(/.*)? which is really strange, like if some process with cwd /etc/getty created new shadow file there and then moved it to /etc with preserving attributes.
Ooh, uh, I may have an idea...just a sec...
Agh, yeah. I think this may be triggered by something we do in openQA. For openQA purposes we want/need to have a root account created at install time. So on paths where the installer hides root account creation - including Silverblue - after the install is complete, we switch to a console and do: echo 'root:$root_password' | chpasswd -R $mount where $mount is either /mnt/sysimage (for legacy RPM installs) or /mnt/sysimage/ostree/deploy/fedora*/deploy/*.? (for ostree installs). I did the same thing on my initial manual test install, where I reproduced the problem. But I just did another manual test install and did *not* do the chpasswd thing, and this time g-i-s went through fine. So it looks like that's the cause of the problem :/ Sorry I forgot about this at first. We *do* need to be able to set a root password at install time, though. Can we fix things so our current way of doing this works? Or can either of you suggest an alternative non-interactive way to set a root password at the end of a Silverblue install that would avoid SELinux issues? I suppose I could try doing a chroot'ed restorecon after the chpasswd , or something?
I will think about it. At the moment, I still don't understand why getty_etc_t.
I did confirm that seems to be the problem. I did another test install, went to a console, checked the label on /mnt/sysimage/ostree/deploy/fedora*/deploy/*.?/etc/shadow , it was correct. Did the `echo 'root:$root_password' | chpasswd -R /mnt/sysimage/ostree/deploy/fedora*/deploy/*.?` and checked it again, and it was getty_etc_t . I mean, we're doing this from a tty in the installer environment, so I suppose it sort of makes sense? I then checked that doing `chroot /mnt/sysimage/ostree/deploy/fedora*/deploy/*.? restorecon /etc/shadow` seems to work to restore the correct context. So I've added that to the openQA test code and I'm gonna re-run the tests against a scratch build of shadow-utils with the changes from -5 re-applied, and see how that goes.
From selinux-policy POV it would only make sense if it was getty, or some of its child processes which did not transition toother domain, which created the shadow file. Statically, the getty_etc_t type is assigned to /etc/mgetty(/.*)? so also to all files created there. Dynamically, only getty_t process in etc_t directory will create files/dirs with getty_etc_t because of: files_etc_filetrans(getty_t, getty_etc_t,{ file dir }) There is nothing else. f44# sesearch -T -s getty_t -c process type_transition getty_t abrt_helper_exec_t:process abrt_helper_t; type_transition getty_t courier_exec_t:process system_mail_t; type_transition getty_t exim_exec_t:process system_mail_t; type_transition getty_t login_exec_t:process local_login_t; type_transition getty_t pppd_exec_t:process pppd_t; type_transition getty_t sendmail_exec_t:process system_mail_t; f44# sesearch -T -s getty_t -c file type_transition getty_t etc_t:file getty_etc_t; type_transition getty_t tmp_t:file getty_tmp_t; type_transition getty_t tmp_t:file krb5_host_rcache_t krb5_0.rcache2; type_transition getty_t tmp_t:file krb5_host_rcache_t krb5_23.rcache2; type_transition getty_t tmp_t:file krb5_host_rcache_t krb5_55.rcache2; type_transition getty_t tmpfs_t:file ica_tmpfs_t icastats_0; type_transition getty_t var_lock_t:file getty_lock_t; type_transition getty_t var_log_t:file getty_log_t; type_transition getty_t var_run_t:file getty_var_run_t; So the question now seems to be why getty_t.
That does seem to work. I guess we should still figure out what changed here, though. I guess I'll test with a stock Silverblue image and see how that behaves. I'm curious whether we don't see the context change there, or we *do* see the context change but it doesn't seem to break things...
OK, so I tried again with a random older Silverblue image I had lying around. With that one, the context of /etc/shadow within the ostree root does not change when we do the `chpasswd`, it stays as system_u:object_r:shadow_t:s0 . So, somehow, with the changed shadow-utils - the changes from -4 and -5 - that `chpasswd -R` command causes the context of /etc/shadow to change. With older shadow-utils it did not.
This behavior is a side effect of the fix for https://github.com/shadow-maint/shadow/issues/940, implemented in https://github.com/shadow-maint/shadow/pull/1258 and backported in shadow-utils-4.18.0-5.fc44. Previously, shadow tools would query is_selinux_enabled() against the host system even when operating in a chroot. This caused failures in minimal environments (like Mock builds) where SELinux tools are present but the policy is not loadable or applicable. As decided in the upstream discussion, the solution was to disable SELinux processing entirely when --root/-R or --prefix/-P options are specified. The openQA test runs: echo 'root:$root_password' | chpasswd -R /mnt/sysimage/... Because -R is present, chpasswd now ignores SELinux. It creates the new shadow file without explicitly setting the creation context (setfscreatecon). Since chpasswd is no longer managing the label, the default type is set. The -R flag is intended for manipulating chroots where SELinux is not expected to be active or consistent. The man pages (e.g., useradd(8)) note that SELinux labeling with -R/-P isn't supported.
Still, that seems like you fixed one case only to break another one. It doesn't feel like wanting to do this is particularly unusual. I could imagine somebody might be doing it in the 'real world', not just a test system like me. Is it not possible to just make your `_is_selinux_enabled()` implementation more accurate?
> Since chpasswd is no longer managing the label, the default type is set. Where does such default type come from? I still don't understand why getty. Will passwd -R be working fine or will it suffer from the same problem?
(In reply to Zdenek Pytela from comment #13) > Will passwd -R be working fine or will it suffer from the same problem? Now I see it is every command with -R. No SELINUX support.
You are right, Adam. This is definitely an unintended side-effect of the previous fix. Before I attempt a fix, I need to better understand the requirements. Can you think of any real-world use cases where using the --root / -R option should apply SELinux labels? My assumption for the previous fix was that -R implies an isolated environment (like Mock or containers) where the host's SELinux policy is often irrelevant, missing, or broken, and attempting to use it causes crashes. I can modify is_selinux_enabled() to be more intelligent, but I face a logic problem: how do I distinguish a "valid" SELinux chroot from an "invalid" one? A sysadmin can set any folder as a chroot, so I can't rely on paths.
> Before I attempt a fix, I need to better understand the requirements. Can you think of any real-world use cases where using the --root / -R option should apply SELinux labels? I guess I was thinking of the 'locked out' scenario? Oh, no, I forgot my root password, have to change it from the outside? Granted, maybe most people's default would be an interactive method. I asked Google! https://stackoverflow.com/questions/55430287/how-do-i-create-a-user-set-password-without-user-interaction is from a person trying to gin up an unattended Arch installer, so that'd be relevant if Arch used SELinux I guess, and at least indicates people are aware of this argument for this kinda purpose. https://doc.opensuse.org/documentation/leap/archive/15.2/virtualization/html/book-virt/cha-lxc.html uses it for setting up an LXC container; not sure if you'd ever need/want a functioning SELinux setup in one of those. https://github.com/IBT-FMI/gebuilder/issues/20 is some sort of Gentoo system image builder? I didn't catch the bit before that the tool was querying the *host* environment, to be fair. I agree that makes the old behavior less 'correct' and less important to preserve.
> I didn't catch the bit before that the tool was querying the *host* environment, to be fair. I agree that makes the old behavior less 'correct' and less important to preserve. Yeah, shadow was applying *host* environment rules to the *chroot* system, but that was failing because the chroot is minimal and SELinux is disabled. The best idea that comes to my mind right now is to add an additional option to enable SELinux in chroot environments. This would still break the existing behaviour but it would at least give a solution to those that still want to apply SELinux labels in chroot environments.
It's either that or the user applies the SELinux labeling after the user has been added with the restorecon command
> It's either that or the user applies the SELinux labeling after the user has been added with the restorecon command Yeah, that's what I went with to resolve this issue in openQA. It works. Maybe just document that and call it good?
Let's document it, but where? I don't think the man page update is enough as many people won't read it. Maybe some Fedora RN?
Oh, hey, so I'm back here... I just noticed what I think is another issue related to this. When you create a user during Fedora system installation, if the installer image has shadow-utils 4.19, the user's home directory gets SELinux context home_root_t . That's not correct. If the installer image has shadow-utils 4.18, the directory gets context user_home_dir_t , which is correct. This causes...well, probably lots of problems, but the first one I noticed is that KDE can't create a wallet for the user at login time because SELinux denies it. I've filed https://github.com/rhinstaller/anaconda/pull/6881 to have anaconda always restorecon the home dir after creating it...hopefully that's all we need...
Is that enough? Neither KDE nor GNOME use Anaconda to create users, so the Anaconda fix isn't enough. We'd need Plasma Setup *and* GNOME Initial Setup to do the same thing.
It's only an issue if you use useradd -R (i.e. create the user in a chroot). The change is that useradd no longer does SELinux processing *in that case*. If you're creating a user in the same root you're running useradd from (i.e. not using -R), it still will.
Ah, so only Anaconda and Calamares would need fixing then.
I think we can close this ticket