Open praiskup opened 7 months ago
We (== rpm upstream) ran into this too: we'd like to use useradd/groupadd to create users into an otherwise practically empty chroot during the initial system install, but this selinux related logic prevents it. As @praiskup notes, just creating a fake enforcing file is enough to work around it:
[root@localhost]# rm -rf /srv/test/* [root@localhost]# mkdir -p /srv/test/etc [root@localhost]# groupadd -r -R /srv/test mumble groupadd: failure while writing changes to /etc/group
[root@localhost]# mkdir -p /srv/test/sys/fs/selinux [root@localhost]# echo 0 > /srv/test/sys/fs/selinux/enforce [root@localhost]# groupadd -r -R /srv/test mumble [root@localhost]#
This seems kinda counterproductive. Been there enough to know that SELinux and chroot aren't the best of friends, but few very few things are designed with a totally empty chroot in mind. In that case there are exactly two options: either use the info from the host, or disable. Disable is non-ambiguous, but obviously has other downsides.
I wouldn't mind working on a patch if we can agree on the desireable way to handle it. FWIW the rpm sysusers issue would be sufficiently handled with an explicit flag of some sort (cli switch, env variable).
I'm not a SELinux expert, am I to assume that sys/fs/selinux/enforce
is the file that indicates whether a system (or chroot) has SELinux activated?
Yes.
In that case, my preferred option would be for SELinux to take this into account and provide an interface that we can use to see if SELinux is enabled in the chroot environment. This would also allow other projects to use the same interface to do the same thing.
In case this is not possible shadow should check the sys/fs/selinux/enforce
file manually in the chroot environment and act accordingly.
Consider installing a separate minimal chroot, and then running
useradd --root
(other shadow-utils utility):I used GDB to detect what was going on. It is the call to
set_selinux_file_context ()
at file-descriptor-closing-time.The thing is that
set_selinux_file_context()
is called non-conditionally every time, and it asks foris_selinux_enabled()
- which provides the info about SELinux on-host, not in-chroot:https://github.com/shadow-maint/shadow/blob/3e59e9613ec40c51c19c7bb5c28468e33a4529d5/lib/selinux.c#L47-L52
A further assumption that the
selabel_open()
,selabel_lookup_raw()
, etc. in-chroot will work, is wrong.There are further checks for permissive mode that make shadow utils not fail (in theory): https://github.com/shadow-maint/shadow/blob/e367d111e513a61495213028e8d4ab2e36775790/lib/selinux.c#L66-L68
But one would have to make sure that the
/tmp/newroot/sys/fs/selinux/enforce
file exists first, and contains 0.This problem is causing problems to Mock (RPM chrooted builds). We could fake the
/sys/fs/selinux/enforce
file for sure in Mock (we do other hacks to make things work), though this isn't the ideal solution; the mode in-chroot isn't really "permissive", it is supposed to be "disabled". So we should ideally not even attempt to callselabel_open()
, etc.While I see this probably isn't a mistake of shadow-utils (but rather chroot-unfriendly linbselinux API), I'm curious what is the best way out of this. Could we have a new
--no-selinux
option?Also, note that the manual pages are a bit misleading:
Note the note
No SELinux support.
This seems wrong. Theset_selinux_file_context()
is called with--prefix
exactly the same way as with--root
. It makes people think that--root
works better with SELinux, but that's not truth either.