Skip to content

fix(os): make the SELinux assertion real and match it across both backends - #1043

Merged
kvinwang merged 1 commit into
nextfrom
feat/guest-selinux-parity
Aug 12, 2026
Merged

fix(os): make the SELinux assertion real and match it across both backends#1043
kvinwang merged 1 commit into
nextfrom
feat/guest-selinux-parity

Conversation

@kvinwang

@kvinwang kvinwang commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Problem

CONFIG_SECURITY_SELINUX=y has been in dstack-docker.cfg for a long time and has never done anything.

The kernel is built from the linux-yocto tiny type, which leaves CONFIG_SECURITY off. SECURITY_SELINUX is depends on SECURITY_NETWORK && AUDIT && NET && INET, and SECURITY_NETWORK in turn depends on SECURITY. Kconfig drops a symbol whose dependencies are unmet without saying so, so every production image built from this fragment has run without SELinux while the fragment claimed otherwise.

os/mkosi has had it all along, because x86_64_defconfig sets CONFIG_SECURITY. So the two guest images have been measuring different feature sets, with nothing recording that they differ.

Measured in CVMs, one per image:

Yocto mkosi
/sys/fs/selinux does not exist exists
enforce n/a 0
/sys/kernel/security/lsm file absent capability,selinux
/etc/selinux absent semanage.conf only
docker info security options none none

Fix

Enable the whole chain on Yocto, and assert it on both backends.

There is a second failure mode behind the first, silent in the same way. Compiling SELinux in is not enough — an LSM only registers if CONFIG_LSM names it, and that string's default is selected by DEFAULT_SECURITY_*. Turning on SECURITY without naming a default lands on DEFAULT_SECURITY_DAC:

default "landlock,lockdown,yama,loadpin,safesetid,ipe,bpf" if DEFAULT_SECURITY_DAC

— no selinux. The hooks would build and never initialize, which is exactly the class of silent no-op this PR exists to remove. CONFIG_DEFAULT_SECURITY_SELINUX and the resulting CONFIG_LSM order are therefore both asserted, in both fragments, so neither a defconfig change nor a new DEFAULT_SECURITY_* branch can drop selinux without failing the build.

What this does and does not change

Does not change enforcement. SELinux needs a loaded policy and neither image ships one, so the state after this change is what mkosi already has today: hooks registered, enforce=0, no policy, no security options reported by Docker. Nothing starts being denied.

Does change the kernel's measurements, so it needs the same release coordination as any guest-image change.

Adds the audit subsystem to the Yocto image (AUDIT/AUDITSYSCALL), which SELinux depends on (depends on SECURITY_NETWORK && AUDIT && NET && INET). mkosi already has it, and the Yocto guest kernel log will start carrying audit records where it carried none.

To be precise about what those records are, since it is easy to read this as "SELinux starts logging": they come from the audit subsystem, not from SELinux. Counted over a full boot plus an Incus session on the mkosi image — 32 lines total:

type what it is count
1130 / 1131 SERVICE_START / SERVICE_STOP, from systemd 21
1325 NETFILTER_CFG, when something programs nftables 4
1300 / 1327 SYSCALL / PROCTITLE 6
2000 audit subsystem init 1
1400 (AVC — an SELinux denial) 0

No AVC records, because AVC decisions require a loaded policy. Without one SELinux makes no access decisions and logs nothing at all; setenforce is not a factor either way, and neither image even installs it.

Verification

Merged the fragment onto a kernel-config artifact from a real build (linux-yocto 6.18.24), and separately reproduced the mkosi path from x86_64_defconfig, both with olddefconfig against Linux 6.18.40 source:

Symbol Yocto mkosi
SECURITY y y
SECURITY_NETWORK y y
AUDIT y y
AUDITSYSCALL y y
SECURITY_SELINUX y y
DEFAULT_SECURITY_SELINUX y y
NETWORK_SECMARK y y
SECURITYFS y y

The two CONFIG_LSM strings come out byte-identical. os/mkosi/scripts/check-kernel-config.sh passes on the produced mkosi config. REUSE lint clean.

Not verified: no image was built or booted with this change. The runtime numbers in the table above are from the mkosi image as it already ships, which is the state this brings Yocto to.

Relationship to #1042

Independent — this can merge in either order. Both touch the same region of dstack-docker.cfg, so whichever lands second needs a trivial rebase: #1042 removes the dead CONFIG_SECURITY_SELINUX=y line and documents why, this PR replaces it with a working chain. #1042 also adds a shared kernel-config gate that would then cover these assertions on the Yocto side too, which today only os/mkosi has.

…kends

CONFIG_SECURITY_SELINUX=y has sat in dstack-docker.cfg without effect. The
kernel is built from the linux-yocto "tiny" type, which leaves CONFIG_SECURITY
off, and SELINUX is "depends on SECURITY_NETWORK && AUDIT && NET && INET" with
SECURITY_NETWORK depending on SECURITY. Kconfig drops a symbol whose
dependencies are unmet without saying so, so every production image built from
this fragment has run without SELinux while the fragment claimed otherwise.
os/mkosi has had it all along, because x86_64_defconfig sets CONFIG_SECURITY --
so the two guest images have been measuring different feature sets.

Enabling the chain is not sufficient on its own, and the second failure is
silent in the same way: an LSM only registers if CONFIG_LSM names it, and that
string's default is selected by DEFAULT_SECURITY_*. Turning on SECURITY without
naming a default lands on DEFAULT_SECURITY_DAC, whose list is
"landlock,lockdown,yama,loadpin,safesetid,ipe,bpf" -- selinux absent -- so the
hooks would compile in and never initialize. Both the DEFAULT_SECURITY_SELINUX
choice and the resulting CONFIG_LSM order are therefore asserted in both
fragments, so neither a defconfig change nor a new DEFAULT_SECURITY_* branch can
drop selinux without failing the build.

This does not change enforcement. SELinux needs a loaded policy and neither
image ships one; measured in a CVM on the mkosi image, which has had SELinux all
along, /sys/fs/selinux exists with enforce=0, /etc/selinux holds only
semanage.conf, and `docker info` reports no security options. On the Yocto image
/sys/fs/selinux does not exist at all. What this buys is that both images
measure the same feature set and the hooks can be used later without another
kernel change.

It does change the kernel's measurements, so it needs the same release
coordination as any guest-image change.

Verified by merging the fragment onto a kernel-config artifact from a real build
(linux-yocto 6.18.24) and by reproducing the mkosi path from x86_64_defconfig,
both with olddefconfig against Linux 6.18.40 source. SECURITY, SECURITY_NETWORK,
AUDIT, AUDITSYSCALL, SECURITY_SELINUX, DEFAULT_SECURITY_SELINUX, NETWORK_SECMARK
and SECURITYFS all come out =y on both backends, and the two CONFIG_LSM strings
are byte-identical. os/mkosi's own kernel-config gate passes.
Copilot AI lite review requested due to automatic review settings August 11, 2026 15:55

Copilot AI 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.

Pull request overview

Enables the full SELinux dependency chain for the Yocto-built guest kernel and aligns the mkosi kernel configuration so both guest-image backends consistently build and register SELinux (via DEFAULT_SECURITY_SELINUX + explicit CONFIG_LSM ordering), avoiding silent Kconfig no-ops and backend drift.

Changes:

  • Enable CONFIG_SECURITY, CONFIG_SECURITY_NETWORK, and CONFIG_AUDIT in the Yocto kernel fragment so CONFIG_SECURITY_SELINUX=y actually takes effect.
  • Assert CONFIG_DEFAULT_SECURITY_SELINUX=y and an explicit CONFIG_LSM=... ordering in both Yocto and mkosi kernel configs to ensure SELinux registers predictably.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
os/yocto/layers/meta-dstack/recipes-kernel/linux/files/dstack-docker.cfg Turns the previously-silent SELinux request into an effective configuration by enabling required dependencies and pinning LSM order.
os/mkosi/components/kernel/kernel.config Matches the Yocto SELinux assertions by pinning required symbols and CONFIG_LSM ordering for mkosi builds as well.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread os/mkosi/components/kernel/kernel.config
@kvinwang
kvinwang merged commit fbe749f into next Aug 12, 2026
19 checks passed
@kvinwang
kvinwang deleted the feat/guest-selinux-parity branch August 12, 2026 05:43
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.

2 participants