Re: RFC: earlyinit_t
"Rahul Sandhu" <[email protected]> Thu, 18 Jun 2026 17:18:44 +0000
| Newsgroups | org.kernel.vger.selinux-refpolicy |
|---|---|
| Message-ID | <[email protected]> |
On Thu Jun 18, 2026 at 4:22 PM BST, Russell Coker wrote:
> On Friday, 19 June 2026 00:34:01 AEST Rahul Sandhu wrote:
>> 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.
>
> That was never a problem in the traditional Unix design.
However, it is a problem now!
>
>> 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].
>
> This is a bad idea. The initramfs should just do whatever is needed to m=
ount=20
> real root and nothing more.
I think there are _some_ advantages (e.g., logging; I find journald to
be quite exceptional in this area at least). And yes, I too do find the
extent of stuff created in initramfs frustrating now. Unfortunately, we
don't really have the ability to change this for all of desktop linux,
being outside of the purview of refpolicy's scope, leaving it for us to
deal with.
>
>> 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:
>
> If people continue with the bad idea of processes running from initramfs =
to=20
> multiuser mode there is no other choice.
That's not what's occuring here. systemd holds open various resources
for processes which die off and then later start again, or sometimes do
not even start until later. This means that, using the example of the
journald socket which is created and held open by systemd-init very
early in the boot process, no logs are ever lost, regardless of whether
or not journald is stopped to be re-exec'd.
But, I still think that's somewhat besides the point as current systems
supported by refpolicy have these things occur. I'm looking at this
precisely because of various avc logs, etc which would require giving
more access to kernel_t, something which I'm really not a fan of doing
myself given the high security nature of kernel threads.
>
>> 1. Does earlyinit_t belong in the kernel policy module or would a new
>> policy module, earlyinit, be preferable?
>
> Probably best to have a new module and make it optional for systems that =
don't=20
> do that sort of thing.
I don't see what is served by making it optional; the sid exists either
way, it's just kernel_t. If anything, systems which don't do this sort
of thing stand the most to gain in terms of security improvements.
>
>> 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.
>
> With the unconfined.pp module loaded the domains init_t, initrc_t, and=20
> kernel_t are all unconfined. But I think we should be aiming for less=20
> unconfined domains not more.
>
>> 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.
>
> Systems without the unconfined module work well currently with a few twea=
ks.
They do! I'm not denying that at all, and I think they work well at the
moment because of the various "subsystem unconfined" stuff that exists,
an example being files_manage_all_files(). The point is exactly that:
for a fair few domain, no real meaningful confinement exists (e.g. the
init process for systemd). I'm not saying this is a fault of policy; if
anything quite the opposite, and I think it's wise to take the step of
accepting some of these things as somewhat scopeless. To further expand
on my systemd example, it basically needs to read any file in theory,
it would also need to getattr and mount on any file for sandboxing. It
can load SELinux policy, and has such broad, sweeping access that most
of the rules are simply there to grant it as close to full access of
the system as possible. Without commenting on this design from init's
perspective, I _do_ think that the _policy_ choice of accepting init's
scope under systemd is a good one, namely because trying to fight what
the upstream of a piece of software expects breaks robustness of policy
with practically zero security advancements. Even if we meticulously
went around adding type attributes to files systemd can sandbox, or the
dev nodes it can relabel, etc, the accesses would be pretty much just
as broad anyway, and even if they weren't, a comprimised systemd-init
can just simply load a new policy, or modify the boot chain, etc.
>
>> 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.
>
> The problem with this is demonstrated by all the ifdef(`distro_ubuntu',`=
=20
> sections in the current policy, they have 19 domains unconfined that ever=
yone=20
> else has confined. Removing the unconfined module is a way of quickly fi=
xing=20
> that on an Ubuntu system.
>
Hm, that's frustrating. Maybe we could gatekeep this behind a tunable
or something akin to that for Ubuntu users?
>> [1]
>> https://github.com/SELinuxProject/refpolicy/pull/1164#issuecomment-47276=
043
>> 62 [2] avc: denied { read write } for pid=3D1183 comm=3D"systemd-udev=
d"
>> path=3D"socket:[3032]" dev=3D"sockfs" ino=3D3032
>> scontext=3Dsystem_u:system_r:udev_t:s0 tcontext=3Dsystem_u:system_r:kern=
el_t:s0
>> tclass=3Dnetlink_kobject_uevent_socket permissive=3D1