| Summary: | SELinux-related "chpasswd: failure while writing changes to /etc/shadow" for systemd container | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Robert Scheck <redhat-bugzilla> |
| Component: | libselinux | Assignee: | Petr Lautrbach <plautrba> |
| Status: | CLOSED WONTFIX | QA Contact: | Milos Malik <mmalik> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | 7.2 | CC: | cww, dwalsh, lvrabec, mgrepl, mmalik, nmavrogi, pkis, plautrba, ssekidde, tmraz, vmojzis, zpytela |
| Target Milestone: | rc | Keywords: | SELinux |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2018-06-22 13:16:49 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Bug Depends On: | |||
| Bug Blocks: | 1477664 | ||
Cross-filed case 01607069 on the Red Hat customer portal. Robert if SELinux is enabled on the machine, but you want libselinux to say it is disabled inside of the container, you have to mount /sys/fs/selinux read/only. Which as you saw fixed the problem. Not sure how we fix this in any other way. If I understand what you are saying. Daniel, what I don't get: If I don't install selinux-policy-targeted RPM, SELinux should be disabled, right? But /sys/fs/selinux is still read-write for the host (and read-only for the container). The situation I would have expected is that SELinux is disabled, if I don't install a SELinux policy. Additionally, "cat /sys/fs/selinux/enforce" on the host says, that it's 0, thus I would have expected permissive at maximum. Do you get my point? Maybe for clarification: I'm first creating a disk image with CentOS (RHEL), booting that (should have no SELinux due to no selinux-policy-targeted RPM installed) and creating inside a container with CentOS (RHEL) (which has SELinux disabled, too, because there's is no selinux-policy-targeted RPM and /sys/fs/selinux is read-only). But then, trying to run chpasswd from the previously created disk image for the container leads to the mentioned error. I might be wrong here, but how to proper enforce SELinux without a policy? Actually, if I boot the host system without "selinux=0" and also without selinux-policy-targeted installed, dmesg(1) tells during boot: kernel: SELinux: Initializing. kernel: SELinux: Starting in permissive mode This makes me believing that my comment #4 expectation is not that wrong. However, chpasswd is denied until I boot with "selinux=0". Adding this to the cmdline leads to: kernel: SELinux: Disabled at boot. Booting only with "enforcing=0" (no "selinux=0") also leads to the error. Robert, yes some tools do not handle permissive correctly. Which is probably a bug, but having /sys/fs/selinux and the policy means that the system is running in SELinux mode. In order to have SELinux disabled, you should have SELINUX=disabled in /etc/selinux/config, or have SELINUX=0 on the kernel line. Otherwise SELinux is enabled. As I said above the command is not handling SELinux permissive but I guess it could be argued that if I can not fix the labeling even in permissive that should be an error. My original comments was about the issue where you wanted SELinux enabled on the host, but apps within a container to be told that SELInux is disabled (For most containers, this is the way it should be, since we don't want container processes trying to do SELinux stuff.) http://danwalsh.livejournal.com/73099.html selinux-policy-targeted package installed will configure /etc/selinux/config with SELINUX=enforcing flag by default. Changing this to SELINUX=disabled will also boot machine without SELinux. BTW I do not recommend this, especially when you are running multi-tenant container environments. SELinux is your best tool for containing containers. So what is the bug of shadow-utils here? That they report the error even in permissive mode = when security_getenforce() returns 0? The problem is in libselinux which checks SELinux the state only in the library constructor and then uses a cached value. In this case, libselinux is initialized before chroot() when SELinux is "enabled" and since the state is cached, it stays "enabled" even after chroot(). If libselinux was initialized after chroot(), it would detect disabled SELinux. It can be simply reproduced using the following python code: >>> import selinux >>> import os >>> os.chroot('/var/lib/machines/example') >>> selinux.is_selinux_enabled() 1 >>> vs >>> import os >>> os.chroot('/var/lib/machines/example') >>> import selinux >>> selinux.is_selinux_enabled() 0 >>> If it's possible, you can mount selinuxfs and proc into chroot to workaround this problem: # echo -n root:tux | chpasswd -R /var/lib/machines/example/ chpasswd: failure while writing changes to /etc/shadow # mkdir -p /var/lib/machines/example/sys/fs/selinux # mount -t selinuxfs selinuxfs /var/lib/machines/example/sys/fs/selinux # mount -t proc proc /var/lib/machines/example/proc/ # echo -n root:tux | chpasswd -R /var/lib/machines/example/ # echo $? 0 Fix to this issue on selinux side could potentially trigger a permission check that wasn't previously required, thereby breaking existing policies (not to mention performance penalties). You can replace line 31 with the following to avoid the issue: echo -n root:tux | chroot /var/lib/machines/example/ chpasswd |
Description of problem: Changing the password of a systemd container using chpasswd fails, because chpasswd does not properly recognize that SELinux is not enabled: $ echo -n root:tux | chpasswd -R /var/lib/machines/example/ chpasswd: failure while writing changes to /etc/shadow $ $ mount | grep selinuxfs selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime) $ $ cat /sys/fs/selinux/enforce 0$ $ mount -o ro,remount /sys/fs/selinux $ $ echo -n root:tux | chpasswd -R /var/lib/machines/example/ $ Version-Release number of selected component (if applicable): shadow-utils-4.1.5.1-18.el7.x86_64 libselinux-utils is not installed selinux-policy-targeted is not installed How reproducible: Everytime, see above and below. Steps to Reproduce: 1. dd if=/dev/zero of=/tmp/example.img bs=1M count=1200 2. parted /tmp/example.img mktable msdos 3. parted /tmp/example.img mkpart primary ext4 1 -- -0 4. parted /tmp/example.img set 1 boot on 5. kpartx -avs /tmp/example.img 6. mkfs.ext4 /dev/mapper/loop0p1 7. mkdir -p /mnt/example/ 8. mount /dev/mapper/loop0p1 /mnt/example/ 9. yum -y --releasever=7 --nogpg --installroot=/mnt/example install \ systemd passwd centos-release kernel grub2 10. mount --bind /dev /mnt/example/dev 11. mount --bind /proc /mnt/example/proc 12. mount --bind /sys /mnt/example/sys 13. echo "GRUB_TIMEOUT=5" > /mnt/example/etc/default/grub 14. echo "GRUB_DISTRIBUTOR=\"\$(sed 's, release .*$,,g' \ /etc/system-release)\"" >> /mnt/example/etc/default/grub 15. echo "GRUB_DEFAULT=saved" >> /mnt/example/etc/default/grub 16. echo "GRUB_DISABLE_SUBMENU=true" >> /mnt/example/etc/default/grub 17. echo "GRUB_TERMINAL_OUTPUT=\"console\"" >> \ /mnt/example/etc/default/grub 18. echo "GRUB_CMDLINE_LINUX=\" vconsole.keymap=de \ vconsole.font=latarcyrheb-sun16\"" >> \ /mnt/example/etc/default/grub 19. echo "GRUB_DISABLE_RECOVERY=\"true\"" >> \ /mnt/example/etc/default/grub 20. chroot /mnt/example/ grub2-mkconfig -o /boot/grub2/grub.cfg 21. chroot /mnt/example/ grub2-install /dev/loop0 22. umount /mnt/example/dev 23. umount /mnt/example/proc 24. umount /mnt/example/sys 25. umount /mnt/example/ 26. kpartx -dvs /tmp/example.img 27. Boot this image as a virtual machine, e.g. using KVM 28. Run the following commands inside the virtual machine 29. yum -y --releasever=7 --nogpg --installroot=/var/lib/machines/example \ install systemd passwd centos-release 30. systemd-machine-id-setup --root /var/lib/machines/example 31. echo -n root:tux | chpasswd -R /var/lib/machines/example/ 32. Receive: "chpasswd: failure while writing changes to /etc/shadow" Possible workaround: Append "selinux=0" string in step 18 - but why is this needed? There are no SELinux related configurations, so chpassword's libselinux usage should detect such a situation. Actual results: SELinux-related "chpasswd: failure while writing changes to /etc/shadow" for systemd container. Expected results: No failure when running chpasswd. Additional info: I see some similarities to bug #1096123 - even this is not the same issue.