Skip to content

DRAFT: Use init_t for initial userspace SID#1168

Open
aerusso wants to merge 1 commit into
SELinuxProject:mainfrom
aerusso:mrs/init-initial-sid
Open

DRAFT: Use init_t for initial userspace SID#1168
aerusso wants to merge 1 commit into
SELinuxProject:mainfrom
aerusso:mrs/init-initial-sid

Conversation

@aerusso

@aerusso aerusso commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

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 sid statement 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.

@WavyEbuilder WavyEbuilder left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

@aerusso

aerusso commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

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).

Comment thread policy/modules/system/init.te
@pebenito

Copy link
Copy Markdown
Member

This does look promising. However, for me, there is one argument for the earlyinit_t route. If a system did have leftover processes from the initramfs, they would have a default unpriv domain to work in, vs. init_t's extremely high privilege.

(this is discussion, not a decision)

@thesamesam

thesamesam commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

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.

@aerusso

aerusso commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

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:

  1. almost all the initrd stuff
  2. switch root
  3. close all fds
  4. policy load
  5. start real pid 1 (with earlyinit_t -> init_t)

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.

@aerusso

aerusso commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@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.

Comment on lines +54 to +57
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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs an interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants