ostree_ext/
selinux.rs

1//! SELinux-related helper APIs.
2
3use anyhow::Result;
4use fn_error_context::context;
5use std::path::Path;
6
7/// The well-known selinuxfs mount point
8const SELINUX_MNT: &str = "/sys/fs/selinux";
9/// Hardcoded value for SELinux domain capable of setting unknown contexts.
10const INSTALL_T: &str = "install_t";
11
12/// Query for whether or not SELinux is enabled.
13pub fn is_selinux_enabled() -> bool {
14    Path::new(SELINUX_MNT).join("access").exists()
15}
16
17/// Return an error If the current process is not running in the `install_t` domain.
18#[context("Verifying self is install_t SELinux domain")]
19pub fn verify_install_domain() -> Result<()> {
20    // If it doesn't look like SELinux is enabled, then nothing to do.
21    if !is_selinux_enabled() {
22        return Ok(());
23    }
24
25    // If we're not root, there's no need to try to warn because we can only
26    // do read-only operations anyways.
27    if !rustix::process::getuid().is_root() {
28        return Ok(());
29    }
30
31    let self_domain = std::fs::read_to_string("/proc/self/attr/current")?;
32    let is_install_t = self_domain.split(':').any(|x| x == INSTALL_T);
33    if !is_install_t {
34        anyhow::bail!(
35            "Detected SELinux enabled system, but the executing binary is not labeled install_exec_t"
36        );
37    }
38    Ok(())
39}