Skip to content

Commit 65523f7

Browse files
committed
install: Refactor selinux re-execution more
We need to be able to use this in more places; rework things so that we have a handy function. Signed-off-by: Colin Walters <[email protected]>
1 parent 3179ba5 commit 65523f7

File tree

1 file changed

+41
-28
lines changed

1 file changed

+41
-28
lines changed

lib/src/install.rs

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -792,12 +792,12 @@ fn install_create_rootfs(state: &State, opts: InstallBlockDeviceOpts) -> Result<
792792
})
793793
}
794794

795-
struct SourceData {
795+
pub(crate) struct SourceData {
796796
/// The embedded base OSTree commit checksum
797797
#[allow(dead_code)]
798-
commit: String,
798+
pub(crate) commit: String,
799799
/// Whether or not SELinux appears to be enabled in the source commit
800-
selinux: bool,
800+
pub(crate) selinux: bool,
801801
}
802802

803803
#[context("Gathering source data")]
@@ -819,6 +819,42 @@ fn gather_source_data() -> Result<SourceData> {
819819
Ok(SourceData { commit, selinux })
820820
}
821821

822+
/// If we detect that the target ostree commit has SELinux labels,
823+
/// and we aren't passed an override to disable it, then ensure
824+
/// the running process is labeled with install_t so it can
825+
/// write arbitrary labels.
826+
pub(crate) fn reexecute_self_for_selinux_if_needed(
827+
srcdata: &SourceData,
828+
override_disable_selinux: bool,
829+
) -> Result<bool> {
830+
let mut ret_did_override = false;
831+
// If the target state has SELinux enabled, we need to check the host state.
832+
if srcdata.selinux {
833+
let host_selinux = crate::lsm::selinux_enabled()?;
834+
tracing::debug!("Target has SELinux, host={host_selinux}");
835+
if host_selinux {
836+
// /sys/fs/selinuxfs is not normally mounted, so we do that now.
837+
// Because SELinux enablement status is cached process-wide and was very likely
838+
// already queried by something else (e.g. glib's constructor), we would also need
839+
// to re-exec. But, selinux_ensure_install does that unconditionally right now too,
840+
// so let's just fall through to that.
841+
crate::lsm::container_setup_selinux()?;
842+
// This will re-execute the current process (once).
843+
crate::lsm::selinux_ensure_install()?;
844+
} else if override_disable_selinux {
845+
ret_did_override = true;
846+
println!("notice: Target has SELinux enabled, overriding to disable")
847+
} else {
848+
anyhow::bail!(
849+
"Host kernel does not have SELinux support, but target enables it by default"
850+
);
851+
}
852+
} else {
853+
tracing::debug!("Target does not enable SELinux");
854+
}
855+
Ok(ret_did_override)
856+
}
857+
822858
/// Trim, flush outstanding writes, and freeze/thaw the target mounted filesystem;
823859
/// these steps prepare the filesystem for its first booted use.
824860
pub(crate) fn finalize_filesystem(fs: &Utf8Path) -> Result<()> {
@@ -874,31 +910,8 @@ async fn prepare_install(
874910

875911
// Now, deal with SELinux state.
876912
let srcdata = gather_source_data()?;
877-
let mut override_disable_selinux = false;
878-
// If the target state has SELinux enabled, we need to check the host state.
879-
if srcdata.selinux {
880-
let host_selinux = crate::lsm::selinux_enabled()?;
881-
tracing::debug!("Target has SELinux, host={host_selinux}");
882-
if host_selinux {
883-
// /sys/fs/selinuxfs is not normally mounted, so we do that now.
884-
// Because SELinux enablement status is cached process-wide and was very likely
885-
// already queried by something else (e.g. glib's constructor), we would also need
886-
// to re-exec. But, selinux_ensure_install does that unconditionally right now too,
887-
// so let's just fall through to that.
888-
crate::lsm::container_setup_selinux()?;
889-
// This will re-execute the current process (once).
890-
crate::lsm::selinux_ensure_install()?;
891-
} else if config_opts.disable_selinux {
892-
override_disable_selinux = true;
893-
println!("notice: Target has SELinux enabled, overriding to disable")
894-
} else {
895-
anyhow::bail!(
896-
"Host kernel does not have SELinux support, but target enables it by default"
897-
);
898-
}
899-
} else {
900-
tracing::debug!("Target does not enable SELinux");
901-
}
913+
let override_disable_selinux =
914+
reexecute_self_for_selinux_if_needed(&srcdata, config_opts.disable_selinux)?;
902915

903916
// Create our global (read-only) state which gets wrapped in an Arc
904917
// so we can pass it to worker threads too. Right now this just

0 commit comments

Comments
 (0)