Skip to content

Commit cd95717

Browse files
committed
crashdump: add SandboxMetadata field that store relevant data about the sandbox
- only store the binary path for now Signed-off-by: Doru Blânzeanu <[email protected]>
1 parent 920efeb commit cd95717

File tree

8 files changed

+118
-13
lines changed

8 files changed

+118
-13
lines changed

src/hyperlight_host/src/hypervisor/crashdump.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub(crate) struct CrashDumpContext<'a> {
4747
regs: [u64; 27],
4848
xsave: Vec<u8>,
4949
entry: u64,
50+
binary: Option<String>,
51+
filename: Option<String>,
5052
}
5153

5254
impl<'a> CrashDumpContext<'a> {
@@ -55,12 +57,16 @@ impl<'a> CrashDumpContext<'a> {
5557
regs: [u64; 27],
5658
xsave: Vec<u8>,
5759
entry: u64,
60+
binary: Option<String>,
61+
filename: Option<String>,
5862
) -> Self {
5963
Self {
6064
regions,
6165
regs,
6266
xsave,
6367
entry,
68+
binary,
69+
filename,
6470
}
6571
}
6672
}
@@ -94,6 +100,17 @@ impl GuestView {
94100
})
95101
.collect();
96102

103+
// The filename and command line are set to null-terminated strings
104+
let filename = ctx
105+
.filename
106+
.clone()
107+
.map_or_else(|| "\0".to_string(), |s| format!("{}\0", s));
108+
109+
let cmd = ctx
110+
.binary
111+
.clone()
112+
.map_or_else(|| "\0".to_string(), |s| format!("{}\0", s));
113+
97114
// The xsave state is checked as it can be empty
98115
let mut components = vec![];
99116
if !ctx.xsave.is_empty() {
@@ -113,7 +130,7 @@ impl GuestView {
113130
tid: 1,
114131
uid: 0, // User ID
115132
gid: 0, // Group ID
116-
comm: "\0".to_string(),
133+
comm: filename,
117134
ppid: 0, // Parent PID
118135
pgrp: 0, // Process group ID
119136
nice: 0, // Nice value
@@ -126,7 +143,7 @@ impl GuestView {
126143
session: 0, // Session ID of the process
127144
sighold: 0, // Blocked signal
128145
sigpend: 0, // Pending signal
129-
cmd_line: "\0".to_string(),
146+
cmd_line: cmd,
130147

131148
arch_state: Box::new(ArchState {
132149
gpr_state: ctx.regs.to_vec(),

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ use mshv_bindings::{
4848
};
4949
use mshv_ioctls::{Mshv, VcpuFd, VmFd};
5050
use tracing::{instrument, Span};
51-
5251
#[cfg(crashdump)]
53-
use super::crashdump;
52+
use {super::crashdump, crate::sandbox::uninitialized::SandboxMetadata, std::path::Path};
53+
5454
use super::fpu::{FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT};
5555
#[cfg(gdb)]
5656
use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, MshvDebug};
@@ -300,6 +300,8 @@ pub(super) struct HypervLinuxDriver {
300300
debug: Option<MshvDebug>,
301301
#[cfg(gdb)]
302302
gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
303+
#[cfg(crashdump)]
304+
metadata: SandboxMetadata,
303305
}
304306

305307
impl HypervLinuxDriver {
@@ -318,6 +320,7 @@ impl HypervLinuxDriver {
318320
rsp_ptr: GuestPtr,
319321
pml4_ptr: GuestPtr,
320322
#[cfg(gdb)] gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
323+
#[cfg(crashdump)] metadata: SandboxMetadata,
321324
) -> Result<Self> {
322325
let mshv = Mshv::new()?;
323326
let pr = Default::default();
@@ -397,6 +400,8 @@ impl HypervLinuxDriver {
397400
debug,
398401
#[cfg(gdb)]
399402
gdb_conn,
403+
#[cfg(crashdump)]
404+
metadata,
400405
})
401406
}
402407

@@ -717,11 +722,20 @@ impl Hypervisor for HypervLinuxDriver {
717722
regs[25] = sregs.fs.selector as u64; // fs
718723
regs[26] = sregs.gs.selector as u64; // gs
719724

725+
// Get the filename from the binary path
726+
let filename = self.metadata.binary_path.clone().and_then(|path| {
727+
Path::new(&path)
728+
.file_name()
729+
.and_then(|name| name.to_os_string().into_string().ok())
730+
});
731+
720732
Ok(crashdump::CrashDumpContext::new(
721733
&self.mem_regions,
722734
regs,
723735
xsave.buffer.to_vec(),
724736
self.entrypoint,
737+
self.metadata.binary_path.clone(),
738+
filename,
725739
))
726740
}
727741

@@ -842,6 +856,8 @@ mod tests {
842856
pml4_ptr,
843857
#[cfg(gdb)]
844858
None,
859+
#[cfg(crashdump)]
860+
SandboxMetadata { binary_path: None },
845861
)
846862
.unwrap();
847863
}

src/hyperlight_host/src/hypervisor/hyperv_windows.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ use windows::Win32::System::Hypervisor::{
2727
WHV_MEMORY_ACCESS_TYPE, WHV_PARTITION_HANDLE, WHV_REGISTER_VALUE, WHV_RUN_VP_EXIT_CONTEXT,
2828
WHV_RUN_VP_EXIT_REASON, WHV_X64_SEGMENT_REGISTER, WHV_X64_SEGMENT_REGISTER_0,
2929
};
30-
3130
#[cfg(crashdump)]
32-
use super::crashdump;
31+
use {super::crashdump, crate::sandbox::uninitialized::SandboxMetadata, std::path::Path};
32+
3333
use super::fpu::{FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT};
3434
#[cfg(gdb)]
3535
use super::handlers::DbgMemAccessHandlerWrapper;
@@ -58,6 +58,8 @@ pub(crate) struct HypervWindowsDriver {
5858
entrypoint: u64,
5959
orig_rsp: GuestPtr,
6060
mem_regions: Vec<MemoryRegion>,
61+
#[cfg(crashdump)]
62+
metadata: SandboxMetadata,
6163
}
6264
/* This does not automatically impl Send/Sync because the host
6365
* address of the shared memory region is a raw pointer, which are
@@ -68,6 +70,7 @@ unsafe impl Send for HypervWindowsDriver {}
6870
unsafe impl Sync for HypervWindowsDriver {}
6971

7072
impl HypervWindowsDriver {
73+
#[allow(clippy::too_many_arguments)]
7174
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
7275
pub(crate) fn new(
7376
mem_regions: Vec<MemoryRegion>,
@@ -77,6 +80,7 @@ impl HypervWindowsDriver {
7780
entrypoint: u64,
7881
rsp: u64,
7982
mmap_file_handle: HandleWrapper,
83+
#[cfg(crashdump)] metadata: SandboxMetadata,
8084
) -> Result<Self> {
8185
// create and setup hypervisor partition
8286
let mut partition = VMPartition::new(1)?;
@@ -104,6 +108,8 @@ impl HypervWindowsDriver {
104108
entrypoint,
105109
orig_rsp: GuestPtr::try_from(RawPtr::from(rsp))?,
106110
mem_regions,
111+
#[cfg(crashdump)]
112+
metadata,
107113
})
108114
}
109115

@@ -529,11 +535,20 @@ impl Hypervisor for HypervWindowsDriver {
529535
regs[25] = unsafe { sregs.fs.Segment.Selector } as u64; // fs
530536
regs[26] = unsafe { sregs.gs.Segment.Selector } as u64; // gs
531537

538+
// Get the filename from the metadata
539+
let filename = self.metadata.binary_path.clone().and_then(|path| {
540+
Path::new(&path)
541+
.file_name()
542+
.and_then(|name| name.to_os_string().into_string().ok())
543+
});
544+
532545
Ok(crashdump::CrashDumpContext::new(
533546
&self.mem_regions,
534547
regs,
535548
xsave,
536549
self.entrypoint,
550+
self.metadata.binary_path.clone(),
551+
filename,
537552
))
538553
}
539554
}

src/hyperlight_host/src/hypervisor/hypervisor_handler.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ use crate::mem::shared_mem::{GuestSharedMemory, HostSharedMemory, SharedMemory};
5151
#[cfg(gdb)]
5252
use crate::sandbox::config::DebugInfo;
5353
use crate::sandbox::hypervisor::{get_available_hypervisor, HypervisorType};
54+
#[cfg(crashdump)]
55+
use crate::sandbox::uninitialized::SandboxMetadata;
5456
#[cfg(target_os = "linux")]
5557
use crate::signal_handlers::setup_signal_handlers;
5658
use crate::HyperlightError::{
@@ -238,6 +240,7 @@ impl HypervisorHandler {
238240
&mut self,
239241
sandbox_memory_manager: SandboxMemoryManager<GuestSharedMemory>,
240242
#[cfg(gdb)] debug_info: Option<DebugInfo>,
243+
#[cfg(crashdump)] metadata: SandboxMetadata,
241244
) -> Result<()> {
242245
let configuration = self.configuration.clone();
243246

@@ -301,6 +304,8 @@ impl HypervisorHandler {
301304
execution_variables.shm.try_lock().map_err(|e| new_error!("Failed to lock shm: {}", e))?.deref_mut().as_mut().ok_or_else(|| new_error!("shm not set"))?,
302305
#[cfg(gdb)]
303306
&debug_info,
307+
#[cfg(crashdump)]
308+
&metadata,
304309
)?);
305310
}
306311
let hv = hv.as_mut().ok_or_else(|| new_error!("Hypervisor not set"))?;
@@ -822,6 +827,7 @@ pub enum HandlerMsg {
822827
fn set_up_hypervisor_partition(
823828
mgr: &mut SandboxMemoryManager<GuestSharedMemory>,
824829
#[cfg(gdb)] debug_info: &Option<DebugInfo>,
830+
#[cfg(crashdump)] metadata: &SandboxMetadata,
825831
) -> Result<Box<dyn Hypervisor>> {
826832
let mem_size = u64::try_from(mgr.shared_mem.mem_size())?;
827833
let mut regions = mgr.layout.get_memory_regions(&mgr.shared_mem)?;
@@ -884,6 +890,8 @@ fn set_up_hypervisor_partition(
884890
pml4_ptr,
885891
#[cfg(gdb)]
886892
gdb_conn,
893+
#[cfg(crashdump)]
894+
metadata.clone(),
887895
)?;
888896
Ok(Box::new(hv))
889897
}
@@ -897,6 +905,8 @@ fn set_up_hypervisor_partition(
897905
rsp_ptr.absolute()?,
898906
#[cfg(gdb)]
899907
gdb_conn,
908+
#[cfg(crashdump)]
909+
metadata.clone(),
900910
)?;
901911
Ok(Box::new(hv))
902912
}
@@ -914,6 +924,8 @@ fn set_up_hypervisor_partition(
914924
entrypoint_ptr.absolute()?,
915925
rsp_ptr.absolute()?,
916926
HandleWrapper::from(mmap_file_handle),
927+
#[cfg(crashdump)]
928+
metadata.clone(),
917929
)?;
918930
Ok(Box::new(hv))
919931
}

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ use kvm_ioctls::Cap::UserMemory;
2424
use kvm_ioctls::{Kvm, VcpuExit, VcpuFd, VmFd};
2525
use log::LevelFilter;
2626
use tracing::{instrument, Span};
27-
2827
#[cfg(crashdump)]
29-
use super::crashdump;
28+
use {super::crashdump, crate::sandbox::uninitialized::SandboxMetadata, std::path::Path};
29+
3030
use super::fpu::{FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT};
3131
#[cfg(gdb)]
3232
use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, KvmDebug, VcpuStopReason};
@@ -288,6 +288,8 @@ pub(super) struct KVMDriver {
288288
debug: Option<KvmDebug>,
289289
#[cfg(gdb)]
290290
gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
291+
#[cfg(crashdump)]
292+
metadata: SandboxMetadata,
291293
}
292294

293295
impl KVMDriver {
@@ -301,6 +303,7 @@ impl KVMDriver {
301303
entrypoint: u64,
302304
rsp: u64,
303305
#[cfg(gdb)] gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
306+
#[cfg(crashdump)] metadata: SandboxMetadata,
304307
) -> Result<Self> {
305308
let kvm = Kvm::new()?;
306309

@@ -352,6 +355,8 @@ impl KVMDriver {
352355
debug,
353356
#[cfg(gdb)]
354357
gdb_conn,
358+
#[cfg(crashdump)]
359+
metadata,
355360
};
356361

357362
Ok(ret)
@@ -625,6 +630,13 @@ impl Hypervisor for KVMDriver {
625630
regs[25] = sregs.fs.selector as u64; // fs
626631
regs[26] = sregs.gs.selector as u64; // gs
627632

633+
// Get the filename from the metadata
634+
let filename = self.metadata.binary_path.clone().and_then(|path| {
635+
Path::new(&path)
636+
.file_name()
637+
.and_then(|name| name.to_os_string().into_string().ok())
638+
});
639+
628640
// The [`CrashDumpContext`] accepts xsave as a vector of u8, so we need to convert the
629641
// xsave region to a vector of u8
630642
Ok(crashdump::CrashDumpContext::new(
@@ -637,6 +649,8 @@ impl Hypervisor for KVMDriver {
637649
acc
638650
}),
639651
self.entrypoint,
652+
self.metadata.binary_path.clone(),
653+
filename,
640654
))
641655
}
642656

src/hyperlight_host/src/hypervisor/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ pub(crate) mod tests {
347347
};
348348
use crate::mem::ptr::RawPtr;
349349
use crate::sandbox::uninitialized::GuestBinary;
350+
#[cfg(crashdump)]
351+
use crate::sandbox::uninitialized::SandboxMetadata;
350352
use crate::sandbox::{SandboxConfiguration, UninitializedSandbox};
351353
use crate::{new_error, Result};
352354

@@ -407,6 +409,8 @@ pub(crate) mod tests {
407409
gshm,
408410
#[cfg(gdb)]
409411
None,
412+
#[cfg(crashdump)]
413+
SandboxMetadata { binary_path: None },
410414
)?;
411415

412416
hv_handler.execute_hypervisor_handler_action(HypervisorHandlerAction::Initialise)

src/hyperlight_host/src/sandbox/uninitialized.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ const EXTRA_ALLOWED_SYSCALLS_FOR_WRITER_FUNC: &[super::ExtraAllowedSyscall] = &[
5555
libc::SYS_close,
5656
];
5757

58+
#[cfg(crashdump)]
59+
#[derive(Clone, Debug, Default)]
60+
pub(crate) struct SandboxMetadata {
61+
pub(crate) binary_path: Option<String>,
62+
}
63+
5864
/// A preliminary `Sandbox`, not yet ready to execute guest code.
5965
///
6066
/// Prior to initializing a full-fledged `Sandbox`, you must create one of
@@ -73,6 +79,8 @@ pub struct UninitializedSandbox {
7379
pub(crate) max_guest_log_level: Option<LevelFilter>,
7480
#[cfg(gdb)]
7581
pub(crate) debug_info: Option<DebugInfo>,
82+
#[cfg(crashdump)]
83+
pub(crate) metadata: SandboxMetadata,
7684
}
7785

7886
impl crate::sandbox_state::sandbox::UninitializedSandbox for UninitializedSandbox {
@@ -153,15 +161,25 @@ impl UninitializedSandbox {
153161
let path = Path::new(&binary_path)
154162
.canonicalize()
155163
.map_err(|e| new_error!("GuestBinary not found: '{}': {}", binary_path, e))?;
156-
GuestBinary::FilePath(
157-
path.into_os_string()
158-
.into_string()
159-
.map_err(|e| new_error!("Error converting OsString to String: {:?}", e))?,
160-
)
164+
let path = path
165+
.into_os_string()
166+
.into_string()
167+
.map_err(|e| new_error!("Error converting OsString to String: {:?}", e))?;
168+
169+
GuestBinary::FilePath(path)
161170
}
162171
buffer @ GuestBinary::Buffer(_) => buffer,
163172
};
164173

174+
#[cfg(crashdump)]
175+
let metadata = if let GuestBinary::FilePath(ref path) = guest_binary {
176+
SandboxMetadata {
177+
binary_path: Some(path.clone()),
178+
}
179+
} else {
180+
SandboxMetadata::default()
181+
};
182+
165183
let sandbox_cfg = cfg.unwrap_or_default();
166184

167185
#[cfg(gdb)]
@@ -190,6 +208,8 @@ impl UninitializedSandbox {
190208
max_guest_log_level: None,
191209
#[cfg(gdb)]
192210
debug_info,
211+
#[cfg(crashdump)]
212+
metadata,
193213
};
194214

195215
// If we were passed a writer for host print register it otherwise use the default.

0 commit comments

Comments
 (0)