1use std::array::TryFromSliceError;
18use std::cell::{BorrowError, BorrowMutError};
19use std::convert::Infallible;
20use std::error::Error;
21use std::num::TryFromIntError;
22use std::string::FromUtf8Error;
23use std::sync::{MutexGuard, PoisonError};
24use std::time::SystemTimeError;
25
26#[cfg(target_os = "windows")]
27use crossbeam_channel::{RecvError, SendError};
28use flatbuffers::InvalidFlatbuffer;
29use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnValue};
30use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
31use thiserror::Error;
32
33#[cfg(target_os = "windows")]
34use crate::hypervisor::wrappers::HandleWrapper;
35use crate::mem::memory_region::MemoryRegionFlags;
36use crate::mem::ptr::RawPtr;
37
38#[derive(Error, Debug)]
40pub enum HyperlightError {
41 #[error("Anyhow Error was returned: {0}")]
43 AnyhowError(#[from] anyhow::Error),
44 #[error("Offset: {0} out of bounds, Max is: {1}")]
46 BoundsCheckFailed(u64, usize),
47
48 #[error("Couldn't add offset to base address. Offset: {0}, Base Address: {1}")]
50 CheckedAddOverflow(u64, u64),
51
52 #[error("{0:?}")]
54 #[cfg(target_os = "windows")]
55 CrossBeamReceiveError(#[from] RecvError),
56
57 #[error("{0:?}")]
59 #[cfg(target_os = "windows")]
60 CrossBeamSendError(#[from] SendError<HandleWrapper>),
61
62 #[error("Error converting CString {0:?}")]
64 CStringConversionError(#[from] std::ffi::NulError),
65
66 #[error("{0}")]
68 Error(String),
69
70 #[error("Non-executable address {0:#x} tried to be executed")]
72 ExecutionAccessViolation(u64),
73
74 #[error("Execution was cancelled by the host.")]
76 ExecutionCanceledByHost(),
77
78 #[error("Failed to get a value from flat buffer parameter")]
80 FailedToGetValueFromParameter(),
81
82 #[error("Field Name {0} not found in decoded GuestLogData")]
84 FieldIsMissingInGuestLogData(String),
85
86 #[error("Guest aborted: {0} {1}")]
88 GuestAborted(u8, String),
89
90 #[error("Guest error occurred {0:?}: {1}")]
92 GuestError(ErrorCode, String),
93
94 #[error("Guest execution hung on the execution of a host function call")]
96 GuestExecutionHungOnHostFunctionCall(),
97
98 #[error("Guest call is already in progress")]
100 GuestFunctionCallAlreadyInProgress(),
101
102 #[error("Unsupported type: {0}")]
104 GuestInterfaceUnsupportedType(String),
105
106 #[error("The guest offset {0} is invalid.")]
108 GuestOffsetIsInvalid(usize),
109
110 #[error("HostFunction {0} was not found")]
112 HostFunctionNotFound(String),
113
114 #[error("Reading Writing or Seeking data failed {0:?}")]
116 IOError(#[from] std::io::Error),
117
118 #[error("Failed To Convert Size to usize")]
120 IntConversionFailure(#[from] TryFromIntError),
121
122 #[error("The flatbuffer is invalid")]
124 InvalidFlatBuffer(#[from] InvalidFlatbuffer),
125
126 #[error("Conversion of str data to json failed")]
128 JsonConversionFailure(#[from] serde_json::Error),
129
130 #[error("KVM Error {0:?}")]
132 #[cfg(kvm)]
133 KVMError(#[from] kvm_ioctls::Error),
134
135 #[error("Unable to lock resource")]
137 LockAttemptFailed(String),
138
139 #[error("Memory Access Violation at address {0:#x} of type {1}, but memory is marked as {2}")]
141 MemoryAccessViolation(u64, MemoryRegionFlags, MemoryRegionFlags),
142
143 #[error("Memory Allocation Failed with OS Error {0:?}.")]
145 MemoryAllocationFailed(Option<i32>),
146
147 #[error("Memory Protection Failed with OS Error {0:?}.")]
149 MemoryProtectionFailed(Option<i32>),
150
151 #[error("Memory requested {0} exceeds maximum size allowed {1}")]
153 MemoryRequestTooBig(usize, usize),
154
155 #[error("Metric Not Found {0:?}.")]
157 MetricNotFound(&'static str),
158
159 #[error("mmap failed with os error {0:?}")]
161 MmapFailed(Option<i32>),
162
163 #[error("mprotect failed with os error {0:?}")]
165 MprotectFailed(Option<i32>),
166
167 #[error("mshv Error {0:?}")]
169 #[cfg(mshv3)]
170 MSHVError(#[from] mshv_ioctls::MshvError),
171
172 #[error("No Hypervisor was found for Sandbox")]
174 NoHypervisorFound(),
175
176 #[error("Restore_state called with no valid snapshot")]
178 NoMemorySnapshot,
179
180 #[error("Failed To Convert Parameter Value {0:?} to {1:?}")]
182 ParameterValueConversionFailure(ParameterValue, &'static str),
183
184 #[error("Failure processing PE File {0:?}")]
186 PEFileProcessingFailure(#[from] goblin::error::Error),
187
188 #[error("The sandbox was poisoned")]
207 PoisonedSandbox,
208
209 #[error("Raw pointer ({0:?}) was less than the base address ({1})")]
211 RawPointerLessThanBaseAddress(RawPtr, u64),
212
213 #[error("RefCell borrow failed")]
215 RefCellBorrowFailed(#[from] BorrowError),
216
217 #[error("RefCell mut borrow failed")]
219 RefCellMutBorrowFailed(#[from] BorrowMutError),
220
221 #[error("Failed To Convert Return Value {0:?} to {1:?}")]
223 ReturnValueConversionFailure(ReturnValue, &'static str),
224
225 #[error("Stack overflow detected")]
227 StackOverflow(),
228
229 #[error("Snapshot was taken from a different sandbox")]
231 SnapshotSandboxMismatch,
232
233 #[error("SystemTimeError {0:?}")]
235 SystemTimeError(#[from] SystemTimeError),
236
237 #[error("An error occurred when translating guest address: {0:?}")]
239 #[cfg(gdb)]
240 TranslateGuestAddress(u64),
241
242 #[error("TryFromSliceError {0:?}")]
244 TryFromSliceError(#[from] TryFromSliceError),
245
246 #[error("The number of arguments to the function is wrong: got {0:?} expected {1:?}")]
248 UnexpectedNoOfArguments(usize, usize),
249
250 #[error("The parameter value type is unexpected got {0:?} expected {1:?}")]
252 UnexpectedParameterValueType(ParameterValue, String),
253
254 #[error("The return value type is unexpected got {0:?} expected {1:?}")]
256 UnexpectedReturnValueType(ReturnValue, String),
257
258 #[error("String Conversion of UTF8 data to str failed")]
260 UTF8StringConversionFailure(#[from] FromUtf8Error),
261
262 #[error(
264 "The capacity of the vector is incorrect. Capacity: {0}, Length: {1}, FlatBuffer Size: {2}"
265 )]
266 VectorCapacityIncorrect(usize, usize, i32),
267
268 #[error("vmm sys Error {0:?}")]
270 #[cfg(target_os = "linux")]
271 VmmSysError(vmm_sys_util::errno::Error),
272
273 #[cfg(target_os = "windows")]
275 #[error("Windows API Error Result {0:?}")]
276 WindowsAPIError(#[from] windows_result::Error),
277}
278
279impl From<Infallible> for HyperlightError {
280 fn from(_: Infallible) -> Self {
281 "Impossible as this is an infallible error".into()
282 }
283}
284
285impl From<&str> for HyperlightError {
286 fn from(s: &str) -> Self {
287 HyperlightError::Error(s.to_string())
288 }
289}
290
291impl<T> From<PoisonError<MutexGuard<'_, T>>> for HyperlightError {
292 fn from(e: PoisonError<MutexGuard<'_, T>>) -> Self {
296 let source = match e.source() {
297 Some(s) => s.to_string(),
298 None => String::from(""),
299 };
300 HyperlightError::LockAttemptFailed(source)
301 }
302}
303
304impl HyperlightError {
305 pub(crate) fn is_poison_error(&self) -> bool {
315 match self {
318 HyperlightError::GuestAborted(_, _)
321 | HyperlightError::ExecutionCanceledByHost()
322 | HyperlightError::PoisonedSandbox
323 | HyperlightError::ExecutionAccessViolation(_)
324 | HyperlightError::StackOverflow()
325 | HyperlightError::MemoryAccessViolation(_, _, _) => true,
326
327 HyperlightError::AnyhowError(_)
329 | HyperlightError::BoundsCheckFailed(_, _)
330 | HyperlightError::CheckedAddOverflow(_, _)
331 | HyperlightError::CStringConversionError(_)
332 | HyperlightError::Error(_)
333 | HyperlightError::FailedToGetValueFromParameter()
334 | HyperlightError::FieldIsMissingInGuestLogData(_)
335 | HyperlightError::GuestError(_, _)
336 | HyperlightError::GuestExecutionHungOnHostFunctionCall()
337 | HyperlightError::GuestFunctionCallAlreadyInProgress()
338 | HyperlightError::GuestInterfaceUnsupportedType(_)
339 | HyperlightError::GuestOffsetIsInvalid(_)
340 | HyperlightError::HostFunctionNotFound(_)
341 | HyperlightError::IOError(_)
342 | HyperlightError::IntConversionFailure(_)
343 | HyperlightError::InvalidFlatBuffer(_)
344 | HyperlightError::JsonConversionFailure(_)
345 | HyperlightError::LockAttemptFailed(_)
346 | HyperlightError::MemoryAllocationFailed(_)
347 | HyperlightError::MemoryProtectionFailed(_)
348 | HyperlightError::MemoryRequestTooBig(_, _)
349 | HyperlightError::MetricNotFound(_)
350 | HyperlightError::MmapFailed(_)
351 | HyperlightError::MprotectFailed(_)
352 | HyperlightError::NoHypervisorFound()
353 | HyperlightError::NoMemorySnapshot
354 | HyperlightError::ParameterValueConversionFailure(_, _)
355 | HyperlightError::PEFileProcessingFailure(_)
356 | HyperlightError::RawPointerLessThanBaseAddress(_, _)
357 | HyperlightError::RefCellBorrowFailed(_)
358 | HyperlightError::RefCellMutBorrowFailed(_)
359 | HyperlightError::ReturnValueConversionFailure(_, _)
360 | HyperlightError::SnapshotSandboxMismatch
361 | HyperlightError::SystemTimeError(_)
362 | HyperlightError::TryFromSliceError(_)
363 | HyperlightError::UnexpectedNoOfArguments(_, _)
364 | HyperlightError::UnexpectedParameterValueType(_, _)
365 | HyperlightError::UnexpectedReturnValueType(_, _)
366 | HyperlightError::UTF8StringConversionFailure(_)
367 | HyperlightError::VectorCapacityIncorrect(_, _, _) => false,
368
369 #[cfg(target_os = "windows")]
370 HyperlightError::CrossBeamReceiveError(_) => false,
371 #[cfg(target_os = "windows")]
372 HyperlightError::CrossBeamSendError(_) => false,
373 #[cfg(target_os = "windows")]
374 HyperlightError::WindowsAPIError(_) => false,
375 #[cfg(target_os = "linux")]
376 HyperlightError::VmmSysError(_) => false,
377 #[cfg(kvm)]
378 HyperlightError::KVMError(_) => false,
379 #[cfg(mshv3)]
380 HyperlightError::MSHVError(_) => false,
381 #[cfg(gdb)]
382 HyperlightError::TranslateGuestAddress(_) => false,
383 }
384 }
385}
386
387#[macro_export]
389macro_rules! new_error {
390 ($msg:literal $(,)?) => {{
391 let __args = std::format_args!($msg);
392 let __err_msg = match __args.as_str() {
393 Some(msg) => String::from(msg),
394 None => std::format!($msg),
395 };
396 $crate::HyperlightError::Error(__err_msg)
397 }};
398 ($fmtstr:expr, $($arg:tt)*) => {{
399 let __err_msg = std::format!($fmtstr, $($arg)*);
400 $crate::error::HyperlightError::Error(__err_msg)
401 }};
402}