extrasafe_multiarch/
error.rs

1//! Extrasafe error types
2
3use std::fmt;
4
5#[cfg(feature = "landlock")]
6use std::path::PathBuf;
7
8use seccompiler::Error as SeccompilerError;
9
10#[cfg(feature = "landlock")]
11use landlock::RulesetError as LandlockError;
12#[cfg(feature = "landlock")]
13use landlock::PathFdError;
14
15#[derive(Debug)]
16/// The error type produced by [`crate::SafetyContext`]
17pub enum ExtraSafeError {
18    /// Error created when a simple Seccomp rule would override a conditional rule, or when trying to add a
19    /// conditional rule when there's already a simple rule with the same syscall.
20    ConditionalNoEffectError(crate::syscalls::Sysno, &'static str, &'static str),
21    /// An error from the underlying seccomp library.
22    SeccompError(SeccompilerError),
23    /// No rules were enabled in the SafetyContext.
24    NoRulesEnabled,
25    #[cfg(feature = "landlock")]
26    /// Two landlock rules with the same path were added.
27    DuplicatePath(PathBuf, &'static str, &'static str),
28    #[cfg(feature = "landlock")]
29    /// The path provided to extrasafe in a Landlock rule does not exist or the process does not
30    /// have permission to access it.
31    PathDoesNotExist(PathFdError),
32    #[cfg(feature = "landlock")]
33    /// Conflicting landlock and seccomp rules were added. Unused.
34    LandlockSeccompConflict(&'static str, &'static str),
35    #[cfg(feature = "landlock")]
36    /// Landlock does not support being applied to all threads.
37    LandlockNoThreadSync,
38    #[cfg(feature = "landlock")]
39    /// An error from the underlying landlock library.
40    LandlockError(LandlockError),
41}
42
43impl fmt::Display for ExtraSafeError {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        match self {
46            &Self::ConditionalNoEffectError(sysno, a, b) => write!(
47                f,
48                "A conditional rule on syscall `{}` from RuleSet `{}` would be overridden \
49                by a simple rule from RuleSet `{}`.",
50                sysno, a, b,
51            ),
52            Self::SeccompError(err) => write!(f, "A seccomp error occured {:?}", err),
53            Self::NoRulesEnabled => write!(f, "No rules were enabled in the SafetyContext"),
54            #[cfg(feature = "landlock")]
55            Self::DuplicatePath(path, a, b) => write!(f, "The same path ({:?}) was used in two different landlock rules. Rulesets '{}' and '{}'", path, a, b),
56            #[cfg(feature = "landlock")]
57            Self::PathDoesNotExist(path_error) => write!(f, "Path provided to extrasafe in a landlock rule does not exist or the process does not have permission to access it: {:?}", path_error),
58            #[cfg(feature = "landlock")]
59            Self::LandlockSeccompConflict(a, b) => write!(f, "A seccomp rule and a landlock rule are in conflict. See RuleSets {} and {}", a, b),
60            #[cfg(feature = "landlock")]
61            Self::LandlockError(err) => write!(f, "A Landlock error occurred: {:?}", err),
62            #[cfg(feature = "landlock")]
63            Self::LandlockNoThreadSync => write!(f, "Landlock does not support syncing to all threads"),
64        }
65    }
66}
67
68impl From<SeccompilerError> for ExtraSafeError {
69    fn from(value: SeccompilerError) -> Self {
70        Self::SeccompError(value)
71    }
72}
73
74impl From<seccompiler::BackendError> for ExtraSafeError {
75    fn from(value: seccompiler::BackendError) -> Self {
76        Self::SeccompError(SeccompilerError::from(value))
77    }
78}
79
80impl std::error::Error for ExtraSafeError {
81    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
82        match self {
83            Self::ConditionalNoEffectError(..) => None,
84            Self::NoRulesEnabled => None,
85            Self::SeccompError(err) => Some(err),
86            #[cfg(feature = "landlock")]
87            Self::DuplicatePath(_, _, _) => None,
88            #[cfg(feature = "landlock")]
89            Self::PathDoesNotExist(pathfd_err) => Some(pathfd_err),
90            #[cfg(feature = "landlock")]
91            Self::LandlockSeccompConflict(_, _) => None,
92            #[cfg(feature = "landlock")]
93            Self::LandlockError(err) => Some(err),
94            #[cfg(feature = "landlock")]
95            Self::LandlockNoThreadSync => None,
96        }
97    }
98}
99
100#[cfg(feature = "landlock")]
101impl From<LandlockError> for ExtraSafeError {
102    fn from(value: LandlockError) -> Self {
103        Self::LandlockError(value)
104    }
105}
106
107#[cfg(feature = "landlock")]
108impl From<PathFdError> for ExtraSafeError {
109    fn from(value: PathFdError) -> Self {
110        Self::PathDoesNotExist(value)
111    }
112}