So, we had a large discussion in both #569 and coreos/bugs#2417 about the best way to tackle SELinux labeling. To summarize, the two options were:
(a) create an ignition-relabel.service
unit that runs restorecon
on all the created files
(b) load the policy from the initramfs
In the end, we went with (a). I'd like us to now reconsider option (b). The reason is that there are some pitfalls with (a):
- somewhat goes against the Ignition philosophy of doing everything pre-pivot
All mutations specified in the Ignition config happen pre-pivot. Dumping a relabeling service to "complete the job" post-pivot goes against that.
- (most importantly) running relabeling operations on a booting system is ill-defined/racy
This is also mentioned in the Fedora devel thread I had linked in the PR: basically there is no reliable way to eliminate race conditions with other systemd services that may access mislabelled files. One example of this is systemd-sysctl.service
, which runs earlier than ignition-relabel.service
currently, and thus can trip on drop-in files in /etc/sysctl.d/
. In fact, right now systemd-analyze plot
shows there are more than a dozen services that start before ignition-relabel.service
.
(Un)fortunately AFAIK systemd has no concept of "run this unit first"; i.e. if multiple units have the same Before=
specification, it's still undefined when each will run; they're normally run in parallel. Of course, you could start playing the game of tacking on specific troublesome services in your Before=
but that's hacky and brittle.
In contrast, the pitfall of (b) is that:
- it's heavy-handed and might lead to systemd issues
Loading the policy in the initramfs seems like a big change. The key piece of software this directly affects is systemd. Normally, post-pivot systemd is the one that loads the policy first. However, systemd is designed to deal with pre-loaded policies from the initramfs. First, it always tries to load the policy, regardless of whether a policy is already loaded. Even if it fails (e.g. somehow the policy prevents systemd from loading the policy, which it currently does not, but let's say), systemd will just keep going. Which is fine; we already have the correct policy loaded.
Note that even with the policy being loaded in the initramfs, it would still be best to run a relabeling pass (or using setfscreatecon
at file creation time). Files created by utilities Ignition runs through chroot
will likely be labeled properly. Other files Ignition directly creates might be labeled correctly through the default algorithm (e.g. file transition rules, or inheritance from parent dir), but it might not. So most of the current "file tracking" code used for relabeling would still be needed.
My proposal is to add a new experimental compile time switch which loads the policy in Ignition and performs relabeling as part of the initramfs. We can then enable this switch in FCOS and/or RHCOS and see how it works. If there are major roadblocks, we just drop the experimental switch. If not, we stabilize on the new behaviour for the selinuxRelabel
knob and drop the ignition-relabel.service
path.
Thoughts? Are there other pitfalls with (b) (or major advantages of (a))?