Skip to content

feat(kairos-init): trusted boot selinux recovery mode guard - #5120

Merged
Itxaka merged 4 commits into
kairos-io:masterfrom
thebhdn:feat/uki-selinux-recovery-gate
Oct 8, 2026
Merged

Itxaka merged 4 commits into
kairos-io:masterfrom
thebhdn:feat/uki-selinux-recovery-gate

Conversation

@thebhdn

@thebhdn thebhdn commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Followup #114

Recovery boots carry selinux=0, so the SELinux cloud-config is dead weight there. Gate the relabel unit and file_contexts.subs in addition to the selinux=1 cmdline check. align-selinux-config now pins SELINUX=disabled on recovery so the config matches the kernel.

ACHTUNG - the bug only exists on Trusted Boot

Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
@thebhdn
thebhdn requested a review from a team as a code owner October 1, 2026 20:50
@ci-robbot

Copy link
Copy Markdown
Collaborator

Triage note on this one, since the fix is real but not for the path the test covers.

The bug only exists on Trusted Boot

On GRUB there is nothing to fix. BootArgsCfg in kairos-init/pkg/bundled/bundled.go gates on the image label:

if test "${label}" != "COS_SYSTEM" -a "${selinux_enabled}" == "true"; then
    set baseSelinuxCmd="security=selinux selinux=1 enforcing=0 rd.cos.selinux=${selinux_mode}"
else
    set baseSelinuxCmd="selinux=0"
fi

and both the recovery and statereset menu entries set label=COS_SYSTEM. So on a GRUB recovery boot grep -q "selinux=1" /proc/cmdline is already false, which makes all three hunks no-ops there: the two stanzas already skip, and align-selinux-config already falls through to MODE=disabled.

Where it does bite is UKI. AuroraBoot's pkg/constants/constants.go says it outright:

UkiCmdline is the cmdline every UKI entry is built from ... the same cmdline is reused byte-for-byte into the active, passive, recovery and statereset roles

and pkg/uki/uki.go:328 splices security=selinux selinux=1 enforcing=0 rd.cos.selinux=<mode> into that one base. So a Trusted Boot recovery boot really does carry selinux=1, and this guard is the only thing that would stop the relabel unit there. Worth saying so in the body, because it is the whole justification for the change.

The guard misses the statereset role

sdk/state/state.go:211 maps the UKI statereset entry to AutoReset, and WriteSentinelDagStep then writes autoreset_mode, not recovery_mode. Since statereset reuses the same spliced cmdline, a Trusted Boot state-reset boot still creates the relabel unit and still gets SELINUX=permissive. 00_rootfs.yaml pairs the two sentinels everywhere it gates on recovery ([ -e "/run/cos/recovery_mode" ] || [ -e "/run/cos/autoreset_mode" ]); this should do the same.

The new assertions are tautological in the job that runs them

tests/selinux_test.go runs only in test-core-rocky-9 and test-core-leap, which are GRUB ISO installs (the file header and the OEM grubenv assertion both say so). On that path master already produces no selinux=1 on recovery and already writes SELINUX=disabled, so:

Expect(out).ToNot(ContainSubstring("selinux=1"))
Expect(out).ToNot(ContainSubstring("rd.cos.selinux"))

pass with the patch reverted. The case the fix exists for is a build-uki artifact, which this spec never builds, so the regression would not be caught.

Housekeeping

No closing keyword, so nothing links this to an issue and the board cannot track it. It also overlaps #5121 / kairos-io/AuroraBoot#893, which fix the family gate on the same uki.go splice; the recovery/statereset role gate is a separate half and does not conflict.

CI is green and DCO passes; authorize is the only pending check.

@thebhdn thebhdn changed the title feat(kairos-init): selinux recovery mode guard feat(kairos-init): trusted boot selinux recovery mode guard Oct 2, 2026
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
@Itxaka

Itxaka commented Oct 2, 2026

Copy link
Copy Markdown
Member

umm sysext failing again, my god

@ci-robbot

Copy link
Copy Markdown
Collaborator

@Itxaka that red is not this PR: test-core / install and test-core-fips / install fail identically on master, at install_test.go:197 with /usr/local/bin/usr/bin/edgevpn: No such file or directory, in every run since #5110 landed on 10-01 16:29Z.

Tracked in #5132 and fixed by #5115 (QA passed at 20:32Z today); that PR has been sitting on authorize: waiting since it opened, so it needs a CI approval before it can merge.

@Itxaka
Itxaka merged commit b7418f0 into kairos-io:master Oct 8, 2026
25 checks passed
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.

3 participants