shadow-maint/shadow

The --chroot option doesn't work well with SELinux off in-chroot

praiskup opened this issue · 4 comments

Consider installing a separate minimal chroot, and then running useradd --root (other shadow-utils utility):

$ sudo dnf5 -y --use-host-config --installroot /tmp/newroot install /bin/sh
$ sudo useradd jdoe --root /tmp/newroot
useradd: failure while writing changes to /etc/passwd

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 for is_selinux_enabled() - which provides the info about SELinux on-host, not in-chroot:

shadow/lib/selinux.c

Lines 47 to 52 in 3e59e96

int set_selinux_file_context (const char *dst_name, mode_t mode)
{
if (!selinux_checked) {
selinux_enabled = is_selinux_enabled () > 0;
selinux_checked = true;
}

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):

shadow/lib/selinux.c

Lines 66 to 68 in e367d11

if (security_getenforce () != 0) {
return 1;
}

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 call selabel_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:

       -P, --prefix PREFIX_DIR
           Apply changes to configuration files under the root filesystem
           found under the directory PREFIX_DIR. This option does not chroot
           and is intended for preparing a cross-compilation target. Some
           limitations: NIS and LDAP users/groups are not verified. PAM
           authentication is using the host files. No SELINUX support.

Note the note No SELinux support. This seems wrong. The set_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.