DRAFT: Use init_t for initial userspace SID#1168
Conversation
WavyEbuilder
left a comment
There was a problem hiding this comment.
This is frankly simply put a fantastic change in my opinion. I glossed over the obvious consideration of simply... reusing init_t on the ML, and this looks to be really quite the ideal solution me.
Thank you very much, @aerusso!
|
After using this on a few machines, it appears to work. I expect some profiles that I did not exercise might need some tweaks, but I think this approach is the "correct" one, since the only processes/objects that should outlast initrd are init_t, and this handles issues where load_policy is (somehow) too late to get everything (e.g., dracut loading the policy after handing out some fds). |
|
This does look promising. However, for me, there is one argument for the (this is discussion, not a decision) |
|
I guess the interesting kinds of processes there would be where people run sshd or networkmanager or what-have-you in their initramfs, which would be a worry. I've never done that though so I don't know how the circumstances in which it can live on. |
|
Won't the earlyinit_t need to transition to init_t, then? Also, anything that ran before SELinux loaded is implicitly trusted, given the lack of SELinux policy and (probably) root uid. I understand the concern, it just seems like a lot of unnatural complexity---these fds are properly init_t, just from before policy load. I suppose, ideally, we would have boot proceed as:
That would leave earlyinit_t with very minimal required permissions (basically just the ability to start init_t). But, I don't think that's going to be possible without some kind of significant dracut and/or systemd changes. |
|
@thesamesam I actually use those (remote decrypt over initrd ssh). As far as I can tell, those processes all die off (networkmanager and sshd) before real-root mount. |
| type init_t; | ||
| domain_type(init_t) | ||
| role system_r types init_t; | ||
| sid init gen_context(system_u:system_r:init_t,mls_systemhigh) |
There was a problem hiding this comment.
Move the sid into the init module instead. It will need this after the summary block in init.if:
## <required val="true">
## Required for init initial SID.
## </required>
| kernel_rw_stream_sockets(syslogd_t) | ||
| kernel_rw_unix_dgram_sockets(syslogd_t) | ||
| init_rw_stream_sockets(syslogd_t) | ||
| allow syslogd_t init_t:unix_dgram_socket { getattr ioctl read write }; |
As discussed in #1165, enabling userspace_initial_context disables some legacy compatibility code in the Linux kernel. This causes some socket checks that were being ignored to be now be enforced. This leads to some failures if kernel_t is not unconfined, despite the fact that the initial SID is still kernel_t, both before and after userspace_initial_context. Unfortunately, the initial userspace context is used long past boot-up, so getting the label right matters, both for security and functionality.
This RFC/DRAFT patch takes a different approach. Instead of using kernel_t as the initial SID, init_t is used. A surprisingly small number of fds appear implicated, and therefore not that many permissions need to be converted from kernel_t to init_t.
In addition to comments on the underlying idea, I'm posting this for feedback on the preferred way to use the init_t domain in kernel.te. I get errors if I try to use the
sidstatement in init.te, maybe because the sid is left undefined in kernel.te? Thus, the domain must be defined in kernel.te, and it makes things... unpleasant.