From 6d110f1cd1663f373aba968762b6719ba2934d3b Mon Sep 17 00:00:00 2001 From: Lucy Menon <168595099+syntactically@users.noreply.github.com> Date: Mon, 13 Oct 2025 02:08:54 +0100 Subject: [PATCH] Remove the last vestiges of autodetecting heap/stack size from exes When we supported loading guest binaries from PE files, we also supported autodetecting reasonable defaults for heap and stack size for the sandbox based on the loaded executable's stack/heap size hints. ELF files did not have a similar convention for stack/heap size hints embedded in the file, so when loading an ELF file, we just used some vaguely reasonable small defaults (64k stack and 128k heap). Now that PE support is gone, these are in fact the defaults used for /all/ files, so it doesn't make much sense that we bother putting them into an executable information structure and passing it around. This commit removes that vestigial use of the ExeInfo structure, replacing it with defaults inline in `sandbox::config`. Signed-off-by: Simon Davies --- src/hyperlight_host/src/mem/exe.rs | 17 ----------------- src/hyperlight_host/src/mem/mgr.rs | 4 ++-- src/hyperlight_host/src/sandbox/config.rs | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/src/hyperlight_host/src/mem/exe.rs b/src/hyperlight_host/src/mem/exe.rs index 19b6a9f41..dde991d8e 100644 --- a/src/hyperlight_host/src/mem/exe.rs +++ b/src/hyperlight_host/src/mem/exe.rs @@ -32,13 +32,6 @@ pub enum ExeInfo { Elf(ElfInfo), } -// There isn't a commonly-used standard convention for heap and stack -// limits to be included in ELF files as they are in -// PEs. Consequently, we use these static defaults as the default -// limits, unless overwritten when setting up the sandbox. -const DEFAULT_ELF_STACK_RESERVE: u64 = 65536; -const DEFAULT_ELF_HEAP_RESERVE: u64 = 131072; - #[cfg(feature = "mem_profile")] pub(crate) trait UnwindInfo: Send + Sync { fn as_module(&self) -> framehop::Module>; @@ -84,16 +77,6 @@ impl ExeInfo { pub fn from_buf(buf: &[u8]) -> Result { ElfInfo::new(buf).map(ExeInfo::Elf) } - pub fn stack_reserve(&self) -> u64 { - match self { - ExeInfo::Elf(_) => DEFAULT_ELF_STACK_RESERVE, - } - } - pub fn heap_reserve(&self) -> u64 { - match self { - ExeInfo::Elf(_) => DEFAULT_ELF_HEAP_RESERVE, - } - } pub fn entrypoint(&self) -> Offset { match self { ExeInfo::Elf(elf) => Offset::from(elf.entrypoint_va()), diff --git a/src/hyperlight_host/src/mem/mgr.rs b/src/hyperlight_host/src/mem/mgr.rs index 2434dd118..98233c061 100644 --- a/src/hyperlight_host/src/mem/mgr.rs +++ b/src/hyperlight_host/src/mem/mgr.rs @@ -327,8 +327,8 @@ impl SandboxMemoryManager { let layout = SandboxMemoryLayout::new( cfg, exe_info.loaded_size(), - usize::try_from(cfg.get_stack_size(&exe_info))?, - usize::try_from(cfg.get_heap_size(&exe_info))?, + usize::try_from(cfg.get_stack_size())?, + usize::try_from(cfg.get_heap_size())?, guest_blob_size, guest_blob_mem_flags, )?; diff --git a/src/hyperlight_host/src/sandbox/config.rs b/src/hyperlight_host/src/sandbox/config.rs index dad3420bb..9e8a00521 100644 --- a/src/hyperlight_host/src/sandbox/config.rs +++ b/src/hyperlight_host/src/sandbox/config.rs @@ -21,8 +21,6 @@ use std::time::Duration; use libc::c_int; use tracing::{Span, instrument}; -use crate::mem::exe::ExeInfo; - /// Used for passing debug configuration to a sandbox #[cfg(gdb)] #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -105,6 +103,10 @@ impl SandboxConfiguration { pub const DEFAULT_INTERRUPT_RETRY_DELAY: Duration = Duration::from_micros(500); /// The default signal offset from `SIGRTMIN` used to determine the signal number for interrupting pub const INTERRUPT_VCPU_SIGRTMIN_OFFSET: u8 = 0; + /// The default heap size of a hyperlight sandbox + pub const DEFAULT_HEAP_SIZE: u64 = 131072; + /// The default stack size of a hyperlight sandbox + pub const DEFAULT_STACK_SIZE: u64 = 65536; #[allow(clippy::too_many_arguments)] /// Create a new configuration for a sandbox with the given sizes. @@ -267,17 +269,17 @@ impl SandboxConfiguration { /// If self.stack_size is non-zero, return it. Otherwise, /// return exe_info.stack_reserve() #[instrument(skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn get_stack_size(&self, exe_info: &ExeInfo) -> u64 { + pub(crate) fn get_stack_size(&self) -> u64 { self.stack_size_override_opt() - .unwrap_or_else(|| exe_info.stack_reserve()) + .unwrap_or(Self::DEFAULT_STACK_SIZE) } /// If self.heap_size_override is non-zero, return it. Otherwise, /// return exe_info.heap_reserve() #[instrument(skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn get_heap_size(&self, exe_info: &ExeInfo) -> u64 { + pub(crate) fn get_heap_size(&self) -> u64 { self.heap_size_override_opt() - .unwrap_or_else(|| exe_info.heap_reserve()) + .unwrap_or(Self::DEFAULT_HEAP_SIZE) } } @@ -303,7 +305,6 @@ impl Default for SandboxConfiguration { #[cfg(test)] mod tests { use super::SandboxConfiguration; - use crate::testing::simple_guest_exe_info; #[test] fn overrides() { @@ -325,10 +326,9 @@ mod tests { #[cfg(crashdump)] true, ); - let exe_info = simple_guest_exe_info().unwrap(); - let stack_size = cfg.get_stack_size(&exe_info); - let heap_size = cfg.get_heap_size(&exe_info); + let stack_size = cfg.get_stack_size(); + let heap_size = cfg.get_heap_size(); assert_eq!(STACK_SIZE_OVERRIDE, stack_size); assert_eq!(HEAP_SIZE_OVERRIDE, heap_size);