From bc2e2dcdbf71ed41ac862cb1eff607277b500c20 Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Fri, 6 Mar 2026 16:22:22 -0500 Subject: [PATCH 1/3] install: Label composefs objects as /usr for SELinux The composefs object store currently has no matching SELinux policy for its storage path, so its contents end up labeled as default_t which causes AVC denials at runtime. Explicitly label the composefs directory tree as /usr (giving objects usr_t) after the composefs install completes. Future work should increase the granularity of SELinux behavior here, ideally adding composefs-specific types and policy instead of re-using usr_t. Closes: #1826 Assisted-by: OpenCode (claude-opus-4-6) Signed-off-by: John Eckersberg --- crates/lib/src/install.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index 92cf28144..dbf970d2c 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -1967,6 +1967,19 @@ async fn install_to_filesystem_impl( state.composefs_options.allow_missing_verity, ) .await?; + + // Label composefs objects as /usr so they get usr_t rather than + // default_t (which has no policy match). + if let Some(policy) = state.load_policy()? { + tracing::info!("Labeling composefs objects as /usr"); + crate::lsm::relabel_recurse( + &rootfs.physical_root, + "composefs", + Some("/usr".into()), + &policy, + ) + .context("SELinux labeling of composefs objects")?; + } } else { ostree_install(state, rootfs, cleanup).await?; } From 318d784e9ccdbd38af365829cd30e22110e39483 Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Fri, 6 Mar 2026 16:22:40 -0500 Subject: [PATCH 2/3] install: Add final SELinux relabel of the physical root filesystem Perform a full SELinux relabel pass over the physical root filesystem as the very last step before filesystem finalization. This ensures all files on the physical root have SELinux labels. Files that are already labeled (e.g. ostree deployment contents, composefs objects) are skipped since the relabel only acts on unlabeled files. Assisted-by: OpenCode (claude-opus-4-6) Signed-off-by: John Eckersberg --- crates/lib/src/install.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index dbf970d2c..aede3a863 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -1984,6 +1984,18 @@ async fn install_to_filesystem_impl( ostree_install(state, rootfs, cleanup).await?; } + // As the very last step before filesystem finalization, do a full SELinux + // relabel of the physical root filesystem. Any files that are already + // labeled (e.g. ostree deployment contents, composefs objects) are skipped. + if let Some(policy) = state.load_policy()? { + tracing::info!("Performing final SELinux relabeling of physical root"); + let mut path = Utf8PathBuf::from(""); + crate::lsm::ensure_dir_labeled_recurse(&rootfs.physical_root, &mut path, &policy, None) + .context("Final SELinux relabeling of physical root")?; + } else { + tracing::debug!("Skipping final SELinux relabel (SELinux is disabled)"); + } + // Finalize mounted filesystems if !rootfs.skip_finalize { let bootfs = rootfs.boot.as_ref().map(|_| ("boot", "boot")); From 959c9395bf6be33ea62e516b3c2af302dc7f491c Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Fri, 6 Mar 2026 16:22:45 -0500 Subject: [PATCH 3/3] Remove enforcing=0 for sealed composefs Signed-off-by: John Eckersberg --- contrib/packaging/seal-uki | 4 ---- crates/xtask/src/tmt.rs | 9 +-------- docs/src/experimental-composefs.md | 1 - 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/contrib/packaging/seal-uki b/contrib/packaging/seal-uki index f2d93bd75..66de92ffd 100755 --- a/contrib/packaging/seal-uki +++ b/contrib/packaging/seal-uki @@ -45,10 +45,6 @@ fi # Baseline container ukify options containerukifyargs=(--rootfs "${target}") -# WORKAROUND: SELinux must be permissive for sealed UKI boot -# See https://github.com/bootc-dev/bootc/issues/1826 -containerukifyargs+=(--karg enforcing=0) - missing_verity=() if [[ $allow_missing_verity == "true" ]]; then diff --git a/crates/xtask/src/tmt.rs b/crates/xtask/src/tmt.rs index 6306b4e7e..0766c8a93 100644 --- a/crates/xtask/src/tmt.rs +++ b/crates/xtask/src/tmt.rs @@ -31,10 +31,8 @@ const ENV_BOOTC_UPGRADE_IMAGE: &str = "BOOTC_upgrade_image"; // Distro identifiers const DISTRO_CENTOS_9: &str = "centos-9"; -const COMPOSEFS_KERNEL_ARGS: [&str; 1] = ["--karg=enforcing=0"]; - // Import the argument types from xtask.rs -use crate::{BootType, Bootloader, RunTmtArgs, SealState, TmtProvisionArgs}; +use crate::{Bootloader, RunTmtArgs, SealState, TmtProvisionArgs}; /// Generate a random alphanumeric suffix for VM names fn generate_random_suffix() -> String { @@ -488,11 +486,6 @@ pub(crate) fn run_tmt(sh: &Shell, args: &RunTmtArgs) -> Result<()> { let filesystem = args.filesystem.as_deref().unwrap_or("ext4"); opts.push(format!("--filesystem={}", filesystem)); opts.push("--composefs-backend".into()); - - // UKI install fails with extra args - if args.boot_type == BootType::Bls { - opts.extend(COMPOSEFS_KERNEL_ARGS.map(|x| x.into())); - } } if let Some(b) = &args.bootloader { diff --git a/docs/src/experimental-composefs.md b/docs/src/experimental-composefs.md index 8a72a2201..dd8d1427f 100644 --- a/docs/src/experimental-composefs.md +++ b/docs/src/experimental-composefs.md @@ -159,7 +159,6 @@ The composefs backend is experimental; on-disk formats are subject to change. ### Deployment blockers - [Garbage collection](https://github.com/bootc-dev/bootc/pull/2040): In progress -- [SELinux enforcement](https://github.com/bootc-dev/bootc/issues/1826): Currently requires `enforcing=0` - Extended install APIs: Ability to cleanly implement anaconda %post and osbuild post mutations and general post-install pre-reboot; right now some tools just mount the deployment directory (note this one also relates to [APIs in general](https://github.com/bootc-dev/bootc/issues/522)) - [OCI registry install](https://github.com/bootc-dev/bootc/issues/1703): Installing from registry can fail due to config mismatch (suggestion: just clean reject v2s2) - [composefs-rs repository finalization](https://github.com/bootc-dev/bootc/issues/1320)