Skip to content

Commit f2d5949

Browse files
committed
lsm: Make a not-nosuid /tmp
This was the thing that was breaking our `unconfined_t` -> `install_t` transition; the host `/tmp` is `nosuid`. It simplifies things here to just make our own, so do that. Signed-off-by: Colin Walters <[email protected]>
1 parent 8aff5dd commit f2d5949

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

lib/src/install.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -873,9 +873,22 @@ fn ensure_var() -> Result<()> {
873873
/// We can't bind mount though - we need to symlink it so that each calling process
874874
/// will traverse the link.
875875
#[context("Linking tmp mounts to host")]
876-
pub(crate) fn propagate_tmp_mounts_to_host() -> Result<()> {
877-
// Point our /tmp and /var/tmp at the host, via the /proc/1/root magic link
878-
for path in ["/tmp", "/var/tmp"].map(Utf8Path::new) {
876+
pub(crate) fn setup_tmp_mounts() -> Result<()> {
877+
let st = rustix::fs::statfs("/tmp")?;
878+
if st.f_type == libc::TMPFS_MAGIC {
879+
tracing::trace!("Already have tmpfs /tmp")
880+
} else {
881+
// Note we explicitly also don't want a "nosuid" tmp, because that
882+
// suppresses our install_t transition
883+
Task::new_and_run(
884+
"Mounting tmpfs /tmp",
885+
"mount",
886+
["tmpfs", "-t", "tmpfs", "/tmp"],
887+
)?;
888+
}
889+
890+
// Point our /var/tmp at the host, via the /proc/1/root magic link
891+
for path in ["/var/tmp"].map(Utf8Path::new) {
879892
if path.try_exists()? {
880893
let st = rustix::fs::statfs(path.as_std_path()).context(path)?;
881894
if st.f_type != libc::OVERLAYFS_SUPER_MAGIC {
@@ -999,7 +1012,7 @@ async fn prepare_install(
9991012
}
10001013

10011014
ensure_var()?;
1002-
propagate_tmp_mounts_to_host()?;
1015+
setup_tmp_mounts()?;
10031016

10041017
// Even though we require running in a container, the mounts we create should be specific
10051018
// to this process, so let's enter a private mountns to avoid leaking them.

lib/src/lsm.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,6 @@ fn get_current_security_context() -> Result<String> {
3333
std::fs::read_to_string(SELF_CURRENT).with_context(|| format!("Reading {SELF_CURRENT}"))
3434
}
3535

36-
/// Determine if a security context is the "install_t" type which can
37-
/// write arbitrary labels.
38-
fn context_is_install_t(context: &str) -> bool {
39-
// TODO: we shouldn't actually hardcode this...it's just ugly though
40-
// to figure out whether we really can gain CAP_MAC_ADMIN.
41-
context.contains(":install_t:")
42-
}
43-
4436
#[context("Testing install_t")]
4537
fn test_install_t() -> Result<bool> {
4638
let tmpf = tempfile::NamedTempFile::new()?;
@@ -112,10 +104,6 @@ impl Drop for SetEnforceGuard {
112104
#[cfg(feature = "install")]
113105
pub(crate) fn selinux_ensure_install_or_setenforce() -> Result<Option<SetEnforceGuard>> {
114106
// If the process already has install_t, exit early
115-
let current = get_current_security_context()?;
116-
if context_is_install_t(&current) {
117-
return Ok(None);
118-
}
119107
// Note that this may re-exec the entire process
120108
if selinux_ensure_install()? {
121109
return Ok(None);
@@ -125,6 +113,7 @@ pub(crate) fn selinux_ensure_install_or_setenforce() -> Result<Option<SetEnforce
125113
selinux_set_permissive(true)?;
126114
Some(SetEnforceGuard)
127115
} else {
116+
let current = get_current_security_context()?;
128117
anyhow::bail!("Failed to enter install_t (running as {current}) - use BOOTC_SETENFORCE0_FALLBACK=1 to override");
129118
};
130119
Ok(g)

0 commit comments

Comments
 (0)