RFC: earlyinit_t
"Rahul Sandhu" <[email protected]> Thu, 18 Jun 2026 14:34:01 +0000
| Newsgroups | org.kernel.vger.selinux-refpolicy |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
I'm writing this RFC with reference to the comment that I made earlier
with reference to userspace_initial_context[1]. This is a fairly big
change, but hopefully=E2=80=94once some of the details are ironed out=E2=80=
=94a future
patch could be included in the next release or possibly the one after.
I would be happy to author such a patch myself after some discussion.
kernel_t is currently a bit overloaded in terms of scope; the domain is
used both for kernel threads and early userspace, before the transition
that is done (typically) by the init system.
In terms of the permissions granted via kernel_t, I personally am not
overly concerned. They are _both_, by their nature, highly privileged.
Kernel threads run in the processor's most privileged execution state,
meaning that they have raw access to all memory, disk IO, and various
other pieces of system hardware. This makes SELinux _confinement_ of
said domain somewhat useless.
Early userspace processors are most likely started before policy load
has even occured, meaning that trying to restrict the permissions given
to their domain doesn't really achieve much; the majority, if not all,
of their tasks occur before SELinux is performing any checks.
However, this makes access of other processes _to_ these targets quite
concerning. Given their privileged nature, such domains should be, in
my opinion, considered high value targets.
Unfortunately, these targets differ in terms of the level of access
other domains require to them. Just as an example, modern systems that
are running systemd create a plethora of sockets and other objects in
the initramfs, so long as systemd itself is running there, that persist
for the system's entire boot and onwards. systemd-journald's socket is
a good example of a socket created early, which as a result ends up as
kernel_t. For another example, I have this recent denial from udev[2].
Hence, I propose creating a new domain, earlyinit_t, and changing the
init sid to use that instead of kernel_t. A couple questions linger at
the moment off the top of my head:
1. Does earlyinit_t belong in the kernel policy module or would a new
policy module, earlyinit, be preferable?
2. Is there any desire to add constraints via type enforcement to what
earlyinit_t may do? I'm not currently seeing a usecase, so I think
it may be tempting to give it near limitless permission.
I also would think it desirable to call unconfined_domain(earlyinit_t)
in an optional policy block as that should make the boot more robust in
my opinion.
Is there any contention to calling files_manage_all_files(earlyinit_t),
fs_mount_all_fs(earlyinit_t), etc for each various subsystem? On a side
note, I think it may be useful to move unconfined_domain() to another
module. I can understand not wanting to force unconfined_t and friends
to exist, but I think some domains end up being _basically_ unconfined
but not really simply because we can't call unconfined_domain() always
on them, as it's gated behind an optional policy block. This is another
significant change, but I think the utility to it also extends beyond
this RFC to some other domains and modules, for example init_t running
under systemd.
[1] https://github.com/SELinuxProject/refpolicy/pull/1164#issuecomment-4727=
604362
[2] avc: denied { read write } for pid=3D1183 comm=3D"systemd-udevd" pat=
h=3D"socket:[3032]" dev=3D"sockfs" ino=3D3032 scontext=3Dsystem_u:system_r:=
udev_t:s0 tcontext=3Dsystem_u:system_r:kernel_t:s0 tclass=3Dnetlink_kobject=
_uevent_socket permissive=3D1
--=20
Rahul Sandhu