landlock

Trait RulesetCreatedAttr

source
pub trait RulesetCreatedAttr:
    Sized
    + AsMut<RulesetCreated>
    + Compatible {
    // Provided methods
    fn add_rule<T, U>(self, rule: T) -> Result<Self, RulesetError>
       where T: Rule<U>,
             U: Access { ... }
    fn add_rules<I, T, U, E>(self, rules: I) -> Result<Self, E>
       where I: IntoIterator<Item = Result<T, E>>,
             T: Rule<U>,
             U: Access,
             E: From<RulesetError> { ... }
    fn set_no_new_privs(self, no_new_privs: bool) -> Self { ... }
}

Provided Methods§

source

fn add_rule<T, U>(self, rule: T) -> Result<Self, RulesetError>
where T: Rule<U>, U: Access,

Attempts to add a new rule to the ruleset.

On error, returns a wrapped AddRulesError.

source

fn add_rules<I, T, U, E>(self, rules: I) -> Result<Self, E>
where I: IntoIterator<Item = Result<T, E>>, T: Rule<U>, U: Access, E: From<RulesetError>,

Attempts to add a set of new rules to the ruleset.

On error, returns a (double) wrapped AddRulesError.

§Example

Create a custom iterator to read paths from environment variable.

use landlock::{
    Access, AccessFs, BitFlags, PathBeneath, PathFd, PathFdError, RestrictionStatus, Ruleset,
    RulesetAttr, RulesetCreatedAttr, RulesetError, ABI,
};
use std::env;
use std::ffi::OsStr;
use std::os::unix::ffi::{OsStrExt, OsStringExt};
use thiserror::Error;

#[derive(Debug, Error)]
enum PathEnvError<'a> {
    #[error(transparent)]
    Ruleset(#[from] RulesetError),
    #[error(transparent)]
    AddRuleIter(#[from] PathFdError),
    #[error("missing environment variable {0}")]
    MissingVar(&'a str),
}

struct PathEnv {
    paths: Vec<u8>,
    access: BitFlags<AccessFs>,
}

impl PathEnv {
    // env_var is the name of an environment variable
    // containing paths requested to be allowed.
    // Paths are separated with ":", e.g. "/bin:/lib:/usr:/proc".
    // In case an empty string is provided,
    // no restrictions are applied.
    // `access` is the set of access rights allowed for each of the parsed paths.
    fn new<'a>(
        env_var: &'a str, access: BitFlags<AccessFs>
    ) -> Result<Self, PathEnvError<'a>> {
        Ok(Self {
            paths: env::var_os(env_var)
                .ok_or(PathEnvError::MissingVar(env_var))?
                .into_vec(),
            access,
        })
    }

    fn iter(
        &self,
    ) -> impl Iterator<Item = Result<PathBeneath<PathFd>, PathEnvError<'static>>> + '_ {
        let is_empty = self.paths.is_empty();
        self.paths
            .split(|b| *b == b':')
            // Skips the first empty element from of an empty string.
            .skip_while(move |_| is_empty)
            .map(OsStr::from_bytes)
            .map(move |path|
                Ok(PathBeneath::new(PathFd::new(path)?, self.access)))
    }
}

fn restrict_env() -> Result<RestrictionStatus, PathEnvError<'static>> {
    Ok(Ruleset::default()
        .handle_access(AccessFs::from_all(ABI::V1))?
        .create()?
        // In the shell: export EXECUTABLE_PATH="/usr:/bin:/sbin"
        .add_rules(PathEnv::new("EXECUTABLE_PATH", AccessFs::Execute.into())?.iter())?
        .restrict_self()?)
}
source

fn set_no_new_privs(self, no_new_privs: bool) -> Self

Configures the ruleset to call prctl(2) with the PR_SET_NO_NEW_PRIVS command in restrict_self().

This prctl(2) call is never ignored, even if an error was encountered on a Ruleset or RulesetCreated method call while CompatLevel::SoftRequirement was set.

Object Safety§

This trait is not object safe.

Implementors§