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>;