Skip to main content

sandlock_core/
error.rs

1use thiserror::Error;
2
3/// Root error type for all sandlock operations.
4#[derive(Debug, Error)]
5pub enum SandlockError {
6    #[error("sandbox error: {0}")]
7    Sandbox(#[from] SandboxError),
8
9    #[error("process error: {0}")]
10    Runtime(#[from] SandboxRuntimeError),
11
12    #[error("memory protection error: {0}")]
13    MemoryProtect(String),
14
15    #[error("handler error: {0}")]
16    Handler(#[from] crate::seccomp::dispatch::HandlerError),
17}
18
19/// Errors from sandbox configuration validation and building.
20#[derive(Debug, Error)]
21pub enum SandboxError {
22    #[error("invalid sandbox: {0}")]
23    Invalid(String),
24
25    #[error("max_cpu must be 1-100, got {0}")]
26    InvalidCpuPercent(u8),
27
28    #[error("confine() only accepts Landlock filesystem policy; unsupported fields: {0}")]
29    UnsupportedForConfine(String),
30
31    #[error("chroot path {path} does not exist or is inaccessible: {source}")]
32    ChrootNotFound {
33        path: std::path::PathBuf,
34        #[source]
35        source: std::io::Error,
36    },
37}
38
39/// Errors from the sandbox process runtime (fork, confinement, child, etc.).
40#[derive(Debug, Error)]
41pub enum SandboxRuntimeError {
42    #[error("fork failed: {0}")]
43    Fork(#[source] std::io::Error),
44
45    #[error("confinement failed: {0}")]
46    Confinement(#[from] ConfinementError),
47
48    #[error("child process error: {0}")]
49    Child(String),
50
51    #[error("branch error: {0}")]
52    Branch(#[from] BranchError),
53
54    #[error("sandbox not running")]
55    NotRunning,
56
57    #[error("io error: {0}")]
58    Io(#[from] std::io::Error),
59}
60
61#[derive(Debug, Error)]
62pub enum ConfinementError {
63    #[error("landlock unavailable: {0}")]
64    LandlockUnavailable(String),
65
66    /// A `Protection` in `ProtectionState::Strict` is unavailable
67    /// because the host kernel's Landlock ABI is below the
68    /// protection's `min_abi()`. Build (or `confine`) refuses to
69    /// proceed; the caller can resolve by setting that protection to
70    /// `Degradable` or `Disabled`, or by running on a kernel that
71    /// supports it.
72    #[error("required protection {protection:?} is not available: host Landlock ABI is v{host_abi}, requires v{required_abi}")]
73    ProtectionUnavailable {
74        protection: crate::protection::Protection,
75        required_abi: u32,
76        host_abi: u32,
77    },
78
79    #[error("landlock error: {0}")]
80    Landlock(String),
81
82    #[error("seccomp error: {0}")]
83    Seccomp(#[from] SeccompError),
84}
85
86#[derive(Debug, Error)]
87pub enum SeccompError {
88    #[error("seccomp filter installation failed: {0}")]
89    FilterInstall(String),
90
91    #[error("notification error: {0}")]
92    Notif(#[from] NotifError),
93}
94
95#[derive(Debug, Error)]
96pub enum NotifError {
97    #[error("notification supervisor error: {0}")]
98    Supervisor(String),
99
100    #[error("child memory read failed: {0}")]
101    ChildMemoryRead(#[source] std::io::Error),
102
103    #[error("notification ioctl failed: {0}")]
104    Ioctl(#[source] std::io::Error),
105}
106
107#[derive(Debug, Error)]
108pub enum BranchError {
109    #[error("branch operation failed: {0}")]
110    Operation(String),
111
112    #[error("branch conflict: {0}")]
113    Conflict(String),
114
115    #[error("disk quota exceeded")]
116    QuotaExceeded,
117
118    #[error("file already exists")]
119    Exists,
120}
121
122/// Convenience type alias.
123pub type Result<T> = std::result::Result<T, SandlockError>;