Skip to content

Commit 8aff5dd

Browse files
committed
lsm: Test if we have install_t capability
Hardcoding `install_t` is a bit ugly; maybe at some point things change so that `spc_t` has `install_t` privileges. Let's do a runtime check if we can set an invalid label; if so then we're good. Signed-off-by: Colin Walters <[email protected]>
1 parent f45f0f0 commit 8aff5dd

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

lib/src/cli.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,9 @@ pub(crate) async fn prepare_for_write() -> Result<()> {
293293
}
294294
ensure_self_unshared_mount_namespace().await?;
295295
if crate::lsm::selinux_enabled()? {
296-
crate::lsm::selinux_ensure_install()?;
296+
if !crate::lsm::selinux_ensure_install()? {
297+
tracing::warn!("Do not have install_t capabilities");
298+
}
297299
}
298300
Ok(())
299301
}

lib/src/lsm.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,18 @@ fn context_is_install_t(context: &str) -> bool {
4141
context.contains(":install_t:")
4242
}
4343

44+
#[context("Testing install_t")]
45+
fn test_install_t() -> Result<bool> {
46+
let tmpf = tempfile::NamedTempFile::new()?;
47+
let st = Command::new("chcon")
48+
.args(["-t", "invalid_bootcinstall_testlabel_t"])
49+
.arg(tmpf.path())
50+
.status()?;
51+
Ok(st.success())
52+
}
53+
4454
#[context("Ensuring selinux install_t type")]
45-
pub(crate) fn selinux_ensure_install() -> Result<()> {
55+
pub(crate) fn selinux_ensure_install() -> Result<bool> {
4656
let guardenv = "_bootc_selinuxfs_mounted";
4757
let current = get_current_security_context()?;
4858
tracing::debug!("Current security context is {current}");
@@ -54,9 +64,13 @@ pub(crate) fn selinux_ensure_install() -> Result<()> {
5464
} else {
5565
tracing::debug!("Assuming we now have a privileged (e.g. install_t) label");
5666
}
57-
return Ok(());
67+
return test_install_t();
68+
}
69+
if test_install_t()? {
70+
tracing::debug!("We have install_t");
71+
return Ok(true);
5872
}
59-
tracing::debug!("Copying self to temporary file for re-exec");
73+
tracing::debug!("Lacking install_t capabilities; copying self to temporary file for re-exec");
6074
// OK now, we always copy our binary to a tempfile, set its security context
6175
// to match that of /usr/bin/ostree, and then re-exec. This is really a gross
6276
// hack; we can't always rely on https://github.com/fedora-selinux/selinux-policy/pull/1500/commits/67eb283c46d35a722636d749e5b339615fe5e7f5
@@ -102,18 +116,16 @@ pub(crate) fn selinux_ensure_install_or_setenforce() -> Result<Option<SetEnforce
102116
if context_is_install_t(&current) {
103117
return Ok(None);
104118
}
105-
// Note that this will re-exec the entire process
106-
selinux_ensure_install()?;
107-
let g = if !context_is_install_t(&current) {
108-
if std::env::var_os("BOOTC_SETENFORCE0_FALLBACK").is_some() {
109-
tracing::warn!("Failed to enter install_t; temporarily setting permissive mode");
110-
selinux_set_permissive(true)?;
111-
Some(SetEnforceGuard)
112-
} else {
113-
anyhow::bail!("Failed to enter install_t (running as {current}) - use BOOTC_SETENFORCE0_FALLBACK=1 to override");
114-
}
119+
// Note that this may re-exec the entire process
120+
if selinux_ensure_install()? {
121+
return Ok(None);
122+
}
123+
let g = if std::env::var_os("BOOTC_SETENFORCE0_FALLBACK").is_some() {
124+
tracing::warn!("Failed to enter install_t; temporarily setting permissive mode");
125+
selinux_set_permissive(true)?;
126+
Some(SetEnforceGuard)
115127
} else {
116-
None
128+
anyhow::bail!("Failed to enter install_t (running as {current}) - use BOOTC_SETENFORCE0_FALLBACK=1 to override");
117129
};
118130
Ok(g)
119131
}

0 commit comments

Comments
 (0)