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