ia_sandbox/
errors.rs

1#![allow(clippy::use_self)]
2
3use std::ffi::OsString;
4use std::path::PathBuf;
5use std::result::Result as StdResult;
6
7use serde::{Deserialize, Serialize};
8use thiserror::Error;
9
10#[derive(Error, Debug, Serialize, Deserialize)]
11pub enum FFIError {
12    #[error("Could not chdir to {path:?}: {error}")]
13    ChdirError { path: PathBuf, error: String },
14    #[error("Could not chroot to {path:?}: {error}")]
15    ChrootError { path: PathBuf, error: String },
16    #[error("Could not clone process: {0}")]
17    CloneError(String),
18    #[error("Could not dup file descriptor {name}({fd}): {error}")]
19    DupFdError {
20        fd: i32,
21        name: String,
22        error: String,
23    },
24    #[error("Could not create directory {path:?}: {error}")]
25    CreateDirError { path: PathBuf, error: String },
26    #[error("Could not exec {command:?} (arguments: {arguments:?}): {error}")]
27    ExecError {
28        command: PathBuf,
29        arguments: Vec<OsString>,
30        error: String,
31    },
32    #[error("Could not mount path: {path:?}: {error}")]
33    MountError { path: PathBuf, error: String },
34    #[error("Could not open file descriptor {name}({fd}): {error}")]
35    OpenFdError {
36        fd: i32,
37        name: String,
38        error: String,
39    },
40    #[error("Could not disable aslr: {0}")]
41    PersonalityError(String),
42    #[error("Could not create pipe: {0}")]
43    Pipe2Error(String),
44    #[error("Could not pivot_root to {new_root:?} with old root at {old_root:?}: {error}")]
45    PivotRootError {
46        new_root: PathBuf,
47        old_root: PathBuf,
48        error: String,
49    },
50    #[error("Could not set process to die when parent dies: {0}")]
51    PrSetPDeathSigError(String),
52    #[error("Could not disable future priveleges on execve: {0}")]
53    PrSetNoNewPrivsError(String),
54    #[error("Could not set interval timer alarm: {0}")]
55    SetITimerError(String),
56    #[error("Could not set process group id of {pid} to {pgid}: {error}")]
57    SetpgidError { pid: i32, pgid: i32, error: String },
58    #[error("Could not set resource `{resource}` limit: {error}")]
59    SetRLimitError { resource: String, error: String },
60    #[error("Could not set a signal handler for {signal}: {error}")]
61    SigActionError { signal: String, error: String },
62    #[error("Could not umount path: {path:?}: {error}")]
63    UMountError { path: PathBuf, error: String },
64    #[error("Could not unshare cgroup namespace: {0}")]
65    UnshareCgroupsError(String),
66    #[error("Could not usleep for {time} microseconds: {error}")]
67    UsleepError { time: u32, error: String },
68    #[error("Could not write /proc/self/uid_map file: {0}")]
69    WriteUidError(String),
70    #[error("Could not write /proc/self/uid_map file: {0}")]
71    WriteGidError(String),
72    #[error("Could not wait for process: {0}")]
73    WaitPidError(String),
74    #[error("Could not write /proc/self/setgroups file: {0}")]
75    WriteSetGroupsError(String),
76}
77
78#[derive(Error, Debug, Serialize, Deserialize)]
79pub enum CgroupsError {
80    #[error("Cgroups hierarchy missing: {0:?}")]
81    HierarchyMissing(PathBuf),
82    #[error("Could not clear instance hierarchy at {hierarchy_path:?}: {error}")]
83    InstanceClearError {
84        hierarchy_path: PathBuf,
85        error: String,
86    },
87    #[error(
88        "Could not create instance hierarchy under {hierarchy_path:?} for {instance_name:?}: {error}",
89    )]
90    InstanceHierarchyCreateError {
91        hierarchy_path: PathBuf,
92        instance_name: OsString,
93        error: String,
94    },
95    #[error("Could not open {file:?} for hierarchy {hierarchy_path:?}: {error}")]
96    OpenCgroupsFileError {
97        hierarchy_path: PathBuf,
98        file: PathBuf,
99        error: String,
100    },
101    #[error("Could not parse `{buffer}` from {file:?} for hierarchy {hierarchy_path:?}: {error}")]
102    ParseCgroupsFileError {
103        hierarchy_path: PathBuf,
104        file: PathBuf,
105        buffer: String,
106        error: String,
107    },
108
109    #[error("Could not read from {file:?} for hierarchy {hierarchy_path:?}: {error}")]
110    ReadCgroupsFileError {
111        hierarchy_path: PathBuf,
112        file: PathBuf,
113        error: String,
114    },
115    #[error("Could not find field `{field}` in file {file:?} inside hierarchy {hierarchy_path:?}")]
116    MissingFieldError {
117        hierarchy_path: PathBuf,
118        file: PathBuf,
119        field: String,
120    },
121    #[error("Could not write to {file:?} for hierarchy {hierarchy_path:?}: {error}")]
122    WriteCgroupsFileError {
123        hierarchy_path: PathBuf,
124        file: PathBuf,
125        error: String,
126    },
127}
128
129#[derive(Error, Debug, Serialize, Deserialize)]
130pub enum ChildError {
131    #[error("Caps error occurred: {0}")]
132    CapsError(i32),
133    #[error("Cgroups error occurred.")]
134    CgroupsError(#[from] CgroupsError),
135    #[error("FFI Error occurred.")]
136    FFIError(#[from] FFIError),
137}
138
139impl From<capctl::Error> for ChildError {
140    fn from(err: capctl::Error) -> Self {
141        Self::CapsError(err.code())
142    }
143}
144
145#[derive(Error, Debug, Serialize, Deserialize)]
146pub enum Error {
147    #[error("Cgroups error occurred.")]
148    CgroupsError(#[from] CgroupsError),
149    #[error("Child process error occurred.")]
150    ChildError(#[from] ChildError),
151    #[error("Child process successfully completed even though it used exec")]
152    ContinuedPastExecError(String),
153    #[error("Could not deserialize process result: {}", _0)]
154    DeserializeError(String),
155    #[error("FFI Error occurred.")]
156    FFIError(#[from] FFIError),
157    #[error("Child process stopped/continued unexpected")]
158    StoppedContinuedError,
159    #[error("Supervisor process died and could not collect execution information")]
160    SupervisorProcessDiedError,
161}
162
163pub type Result<T> = StdResult<T, Error>;