Skip to content

Commit 51ce291

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 e14ac69 commit 51ce291

File tree

8 files changed

+118
-13
lines changed

8 files changed

+118
-13
lines changed

src/hyperlight_host/src/hypervisor/crashdump.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub(crate) struct CrashDumpContext<'a> {
2222
regs: [u64; 27],
2323
xsave: Vec<u8>,
2424
entry: u64,
25+
binary: Option<String>,
26+
filename: Option<String>,
2527
}
2628

2729
impl<'a> CrashDumpContext<'a> {
@@ -30,12 +32,16 @@ impl<'a> CrashDumpContext<'a> {
3032
regs: [u64; 27],
3133
xsave: Vec<u8>,
3234
entry: u64,
35+
binary: Option<String>,
36+
filename: Option<String>,
3337
) -> Self {
3438
Self {
3539
regions,
3640
regs,
3741
xsave,
3842
entry,
43+
binary,
44+
filename,
3945
}
4046
}
4147
}
@@ -69,6 +75,17 @@ impl GuestView {
6975
})
7076
.collect();
7177

78+
// The filename and command line are set to null-terminated strings
79+
let filename = ctx
80+
.filename
81+
.clone()
82+
.map_or_else(|| "\0".to_string(), |s| format!("{}\0", s));
83+
84+
let cmd = ctx
85+
.binary
86+
.clone()
87+
.map_or_else(|| "\0".to_string(), |s| format!("{}\0", s));
88+
7289
// The xsave state is checked as it can be empty
7390
let mut components = vec![];
7491
if !ctx.xsave.is_empty() {
@@ -88,7 +105,7 @@ impl GuestView {
88105
tid: 1,
89106
uid: 0, // User ID
90107
gid: 0, // Group ID
91-
comm: "\0".to_string(),
108+
comm: filename,
92109
ppid: 0, // Parent PID
93110
pgrp: 0, // Process group ID
94111
nice: 0, // Nice value
@@ -101,7 +118,7 @@ impl GuestView {
101118
session: 0, // Session ID of the process
102119
sighold: 0, // Blocked signal
103120
sigpend: 0, // Pending signal
104-
cmd_line: "\0".to_string(),
121+
cmd_line: cmd,
105122

106123
arch_state: Box::new(ArchState {
107124
gpr_state: ctx.regs.to_vec(),

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

+18-2
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

+17-2
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

+12
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

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

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

src/hyperlight_host/src/hypervisor/mod.rs

+4
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

+25-5
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)