Skip to content

Commit aea91c8

Browse files
authored
Merge pull request #60 from cgwalters/reexec-prep2
install: Refactor selinux re-execution more
2 parents 88d1320 + 65523f7 commit aea91c8

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
@@ -803,12 +803,12 @@ fn install_create_rootfs(state: &State, opts: InstallBlockDeviceOpts) -> Result<
803803
})
804804
}
805805

806-
struct SourceData {
806+
pub(crate) struct SourceData {
807807
/// The embedded base OSTree commit checksum
808808
#[allow(dead_code)]
809-
commit: String,
809+
pub(crate) commit: String,
810810
/// Whether or not SELinux appears to be enabled in the source commit
811-
selinux: bool,
811+
pub(crate) selinux: bool,
812812
}
813813

814814
#[context("Gathering source data")]
@@ -830,6 +830,42 @@ fn gather_source_data() -> Result<SourceData> {
830830
Ok(SourceData { commit, selinux })
831831
}
832832

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

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

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

0 commit comments

Comments
 (0)