diff --git a/lib/src/install.rs b/lib/src/install.rs index 26ef7884..14d2a811 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -1242,6 +1242,20 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> { loopback_dev.close()?; } + // At this point, all other threads should be gone. + if let Some(state) = Arc::into_inner(state) { + // If we had invoked `setenforce 0`, then let's re-enable it. + match state.selinux_state { + SELinuxFinalState::Enabled(Some(guard)) => { + guard.consume()?; + } + _ => {} + } + } else { + // This shouldn't happen...but we will make it not fatal right now + tracing::warn!("Failed to consume state Arc"); + } + installation_complete(); Ok(()) diff --git a/lib/src/lsm.rs b/lib/src/lsm.rs index 1d56eb45..d53381a2 100644 --- a/lib/src/lsm.rs +++ b/lib/src/lsm.rs @@ -99,12 +99,29 @@ pub(crate) fn selinux_ensure_install() -> Result { /// gain the `mac_admin` permission (install_t). #[cfg(feature = "install")] #[must_use] -pub(crate) struct SetEnforceGuard; +pub(crate) struct SetEnforceGuard(Option<()>); + +#[cfg(feature = "install")] +impl SetEnforceGuard { + pub(crate) fn new() -> Self { + SetEnforceGuard(Some(())) + } + + pub(crate) fn consume(mut self) -> Result<()> { + // SAFETY: The option cannot have been consumed until now + self.0.take().unwrap(); + // This returns errors + selinux_set_permissive(false) + } +} #[cfg(feature = "install")] impl Drop for SetEnforceGuard { fn drop(&mut self) { - let _ = selinux_set_permissive(false); + // A best-effort attempt to re-enable enforcement on drop (installation failure) + if let Some(()) = self.0.take() { + let _ = selinux_set_permissive(false); + } } } @@ -121,7 +138,7 @@ pub(crate) fn selinux_ensure_install_or_setenforce() -> Result