Skip to content

Commit 1b49eed

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 7f464bc commit 1b49eed

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
@@ -31,6 +31,8 @@ pub(crate) struct CrashDumpContext<'a> {
3131
regs: [u64; 27],
3232
xsave: Vec<u8>,
3333
entry: u64,
34+
binary: Option<String>,
35+
filename: Option<String>,
3436
}
3537

3638
impl<'a> CrashDumpContext<'a> {
@@ -39,12 +41,16 @@ impl<'a> CrashDumpContext<'a> {
3941
regs: [u64; 27],
4042
xsave: Vec<u8>,
4143
entry: u64,
44+
binary: Option<String>,
45+
filename: Option<String>,
4246
) -> Self {
4347
Self {
4448
regions,
4549
regs,
4650
xsave,
4751
entry,
52+
binary,
53+
filename,
4854
}
4955
}
5056
}
@@ -78,6 +84,17 @@ impl GuestView {
7884
})
7985
.collect();
8086

87+
// The filename and command line are set to null-terminated strings
88+
let filename = ctx
89+
.filename
90+
.clone()
91+
.map_or_else(|| "\0".to_string(), |s| format!("{}\0", s));
92+
93+
let cmd = ctx
94+
.binary
95+
.clone()
96+
.map_or_else(|| "\0".to_string(), |s| format!("{}\0", s));
97+
8198
// The xsave state is checked as it can be empty
8299
let mut components = vec![];
83100
if !ctx.xsave.is_empty() {
@@ -97,7 +114,7 @@ impl GuestView {
97114
tid: 1,
98115
uid: 0, // User ID
99116
gid: 0, // Group ID
100-
comm: "\0".to_string(),
117+
comm: filename,
101118
ppid: 0, // Parent PID
102119
pgrp: 0, // Process group ID
103120
nice: 0, // Nice value
@@ -110,7 +127,7 @@ impl GuestView {
110127
session: 0, // Session ID of the process
111128
sighold: 0, // Blocked signal
112129
sigpend: 0, // Pending signal
113-
cmd_line: "\0".to_string(),
130+
cmd_line: cmd,
114131

115132
arch_state: Box::new(ArchState {
116133
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};
@@ -296,6 +296,8 @@ pub(super) struct HypervLinuxDriver {
296296
debug: Option<MshvDebug>,
297297
#[cfg(gdb)]
298298
gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
299+
#[cfg(crashdump)]
300+
metadata: SandboxMetadata,
299301
}
300302

301303
impl HypervLinuxDriver {
@@ -314,6 +316,7 @@ impl HypervLinuxDriver {
314316
rsp_ptr: GuestPtr,
315317
pml4_ptr: GuestPtr,
316318
#[cfg(gdb)] gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
319+
#[cfg(crashdump)] metadata: SandboxMetadata,
317320
) -> Result<Self> {
318321
let mshv = Mshv::new()?;
319322
let pr = Default::default();
@@ -393,6 +396,8 @@ impl HypervLinuxDriver {
393396
debug,
394397
#[cfg(gdb)]
395398
gdb_conn,
399+
#[cfg(crashdump)]
400+
metadata,
396401
})
397402
}
398403

@@ -696,11 +701,20 @@ impl Hypervisor for HypervLinuxDriver {
696701
regs[25] = sregs.fs.selector as u64; // fs
697702
regs[26] = sregs.gs.selector as u64; // gs
698703

704+
// Get the filename from the binary path
705+
let filename = self.metadata.binary_path.clone().and_then(|path| {
706+
Path::new(&path)
707+
.file_name()
708+
.and_then(|name| name.to_os_string().into_string().ok())
709+
});
710+
699711
Ok(crashdump::CrashDumpContext::new(
700712
&self.mem_regions,
701713
regs,
702714
xsave.buffer.to_vec(),
703715
self.entrypoint,
716+
self.metadata.binary_path.clone(),
717+
filename,
704718
))
705719
}
706720

@@ -821,6 +835,8 @@ mod tests {
821835
pml4_ptr,
822836
#[cfg(gdb)]
823837
None,
838+
#[cfg(crashdump)]
839+
SandboxMetadata { binary_path: None },
824840
)
825841
.unwrap();
826842
}

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

@@ -525,11 +531,20 @@ impl Hypervisor for HypervWindowsDriver {
525531
regs[25] = unsafe { sregs.fs.Segment.Selector } as u64; // fs
526532
regs[26] = unsafe { sregs.gs.Segment.Selector } as u64; // gs
527533

534+
// Get the filename from the metadata
535+
let filename = self.metadata.binary_path.clone().and_then(|path| {
536+
Path::new(&path)
537+
.file_name()
538+
.and_then(|name| name.to_os_string().into_string().ok())
539+
});
540+
528541
Ok(crashdump::CrashDumpContext::new(
529542
&self.mem_regions,
530543
regs,
531544
xsave,
532545
self.entrypoint,
546+
self.metadata.binary_path.clone(),
547+
filename,
533548
))
534549
}
535550
}

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
#[cfg(target_os = "windows")]
@@ -304,6 +307,8 @@ impl HypervisorHandler {
304307
configuration.outb_handler.clone(),
305308
#[cfg(gdb)]
306309
&debug_info,
310+
#[cfg(crashdump)]
311+
&metadata,
307312
)?);
308313
}
309314
let hv = hv.as_mut().ok_or_else(|| new_error!("Hypervisor not set"))?;
@@ -835,6 +840,7 @@ fn set_up_hypervisor_partition(
835840
#[allow(unused_variables)] // parameter only used for in-process mode
836841
outb_handler: OutBHandlerWrapper,
837842
#[cfg(gdb)] debug_info: &Option<DebugInfo>,
843+
#[cfg(crashdump)] metadata: &SandboxMetadata,
838844
) -> Result<Box<dyn Hypervisor>> {
839845
let mem_size = u64::try_from(mgr.shared_mem.mem_size())?;
840846
let mut regions = mgr.layout.get_memory_regions(&mgr.shared_mem)?;
@@ -924,6 +930,8 @@ fn set_up_hypervisor_partition(
924930
pml4_ptr,
925931
#[cfg(gdb)]
926932
gdb_conn,
933+
#[cfg(crashdump)]
934+
metadata.clone(),
927935
)?;
928936
Ok(Box::new(hv))
929937
}
@@ -937,6 +945,8 @@ fn set_up_hypervisor_partition(
937945
rsp_ptr.absolute()?,
938946
#[cfg(gdb)]
939947
gdb_conn,
948+
#[cfg(crashdump)]
949+
metadata.clone(),
940950
)?;
941951
Ok(Box::new(hv))
942952
}
@@ -954,6 +964,8 @@ fn set_up_hypervisor_partition(
954964
entrypoint_ptr.absolute()?,
955965
rsp_ptr.absolute()?,
956966
HandleWrapper::from(mmap_file_handle),
967+
#[cfg(crashdump)]
968+
metadata.clone(),
957969
)?;
958970
Ok(Box::new(hv))
959971
}

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)
@@ -621,6 +626,13 @@ impl Hypervisor for KVMDriver {
621626
regs[25] = sregs.fs.selector as u64; // fs
622627
regs[26] = sregs.gs.selector as u64; // gs
623628

629+
// Get the filename from the metadata
630+
let filename = self.metadata.binary_path.clone().and_then(|path| {
631+
Path::new(&path)
632+
.file_name()
633+
.and_then(|name| name.to_os_string().into_string().ok())
634+
});
635+
624636
// The [`CrashDumpContext`] accepts xsave as a vector of u8, so we need to convert the
625637
// xsave region to a vector of u8
626638
Ok(crashdump::CrashDumpContext::new(
@@ -633,6 +645,8 @@ impl Hypervisor for KVMDriver {
633645
acc
634646
}),
635647
self.entrypoint,
648+
self.metadata.binary_path.clone(),
649+
filename,
636650
))
637651
}
638652

src/hyperlight_host/src/hypervisor/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ pub(crate) mod tests {
350350
};
351351
use crate::mem::ptr::RawPtr;
352352
use crate::sandbox::uninitialized::GuestBinary;
353+
#[cfg(crashdump)]
354+
use crate::sandbox::uninitialized::SandboxMetadata;
353355
use crate::sandbox::{SandboxConfiguration, UninitializedSandbox};
354356
use crate::{new_error, Result};
355357

@@ -411,6 +413,8 @@ pub(crate) mod tests {
411413
gshm,
412414
#[cfg(gdb)]
413415
None,
416+
#[cfg(crashdump)]
417+
SandboxMetadata { binary_path: None },
414418
)?;
415419

416420
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
@@ -39,6 +39,12 @@ use crate::sandbox_state::sandbox::EvolvableSandbox;
3939
use crate::sandbox_state::transition::Noop;
4040
use crate::{log_build_details, log_then_return, new_error, MultiUseSandbox, Result};
4141

42+
#[cfg(crashdump)]
43+
#[derive(Clone, Debug, Default)]
44+
pub(crate) struct SandboxMetadata {
45+
pub(crate) binary_path: Option<String>,
46+
}
47+
4248
/// A preliminary `Sandbox`, not yet ready to execute guest code.
4349
///
4450
/// Prior to initializing a full-fledged `Sandbox`, you must create one of
@@ -58,6 +64,8 @@ pub struct UninitializedSandbox {
5864
pub(crate) max_guest_log_level: Option<LevelFilter>,
5965
#[cfg(gdb)]
6066
pub(crate) debug_info: Option<DebugInfo>,
67+
#[cfg(crashdump)]
68+
pub(crate) metadata: SandboxMetadata,
6169
}
6270

6371
impl crate::sandbox_state::sandbox::UninitializedSandbox for UninitializedSandbox {
@@ -142,15 +150,25 @@ impl UninitializedSandbox {
142150
let path = Path::new(&binary_path)
143151
.canonicalize()
144152
.map_err(|e| new_error!("GuestBinary not found: '{}': {}", binary_path, e))?;
145-
GuestBinary::FilePath(
146-
path.into_os_string()
147-
.into_string()
148-
.map_err(|e| new_error!("Error converting OsString to String: {:?}", e))?,
149-
)
153+
let path = path
154+
.into_os_string()
155+
.into_string()
156+
.map_err(|e| new_error!("Error converting OsString to String: {:?}", e))?;
157+
158+
GuestBinary::FilePath(path)
150159
}
151160
buffer @ GuestBinary::Buffer(_) => buffer,
152161
};
153162

163+
#[cfg(crashdump)]
164+
let metadata = if let GuestBinary::FilePath(ref path) = guest_binary {
165+
SandboxMetadata {
166+
binary_path: Some(path.clone()),
167+
}
168+
} else {
169+
SandboxMetadata::default()
170+
};
171+
154172
let run_opts = sandbox_run_options.unwrap_or_default();
155173

156174
let run_inprocess = run_opts.in_process();
@@ -200,6 +218,8 @@ impl UninitializedSandbox {
200218
max_guest_log_level: None,
201219
#[cfg(gdb)]
202220
debug_info,
221+
#[cfg(crashdump)]
222+
metadata,
203223
};
204224

205225
// TODO: These only here to accommodate some writer functions.

0 commit comments

Comments
 (0)