Skip to content

Commit 620b5e8

Browse files
committed
Allow the guest to manage its own stack
This moves management of the guest stack into the guest, allowing the guest to flexibly allocate pages from the scratch region to the stack. This also makes the stack dynamically growable and essentially unbounded, as is common on other architectures. Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
1 parent 5907be8 commit 620b5e8

30 files changed

Lines changed: 239 additions & 489 deletions

File tree

fuzz/fuzz_targets/guest_trace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fuzz_target!(
7070
init: {
7171
let mut cfg = SandboxConfiguration::default();
7272
// In local tests, 256 KiB seemed sufficient for deep recursion
73-
cfg.set_stack_size(256 * 1024);
73+
cfg.set_scratch_size(256 * 1024);
7474
let path = simple_guest_for_fuzzing_as_string().expect("Guest Binary Missing");
7575
let u_sbox = UninitializedSandbox::new(
7676
GuestBinary::FilePath(path),

src/hyperlight_common/src/arch/amd64/layout.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,13 @@ pub const SNAPSHOT_PT_GVA_MAX: usize = 0xffff_80ff_ffff_ffff;
3030
/// bits, so we could consider bumping this in the future if we were
3131
/// ever memory-constrained.
3232
pub const MAX_GPA: usize = 0x0000_000f_ffff_ffff;
33+
34+
/// On amd64, this is:
35+
/// - Two pages for the TSS and IDT
36+
/// - (up to) 4 pages for the PTEs for mapping that (including CoW'ing the root PT)
37+
/// - A page for the smallest possible non-exception stack
38+
/// - (up to) 3 pages for mapping that
39+
/// - Two pages for the exception stack and metadata
40+
pub fn min_scratch_size() -> usize {
41+
12 * crate::vmem::PAGE_SIZE
42+
}

src/hyperlight_common/src/arch/i686/layout.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ pub const MAX_GVA: usize = 0xffff_efff;
2121
pub const SNAPSHOT_PT_GVA_MIN: usize = 0xef00_0000;
2222
pub const SNAPSHOT_PT_GVA_MAX: usize = 0xefff_efff;
2323
pub const MAX_GPA: usize = 0xffff_ffff;
24+
25+
pub fn min_scratch_size() -> usize {
26+
1 * crate::vmem::PAGE_SIZE
27+
}

src/hyperlight_common/src/flatbuffer_wrappers/guest_error.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ pub enum ErrorCode {
3535
GispatchFunctionPointerNotSet = 6,
3636
OutbError = 7,
3737
UnknownError = 8,
38-
StackOverflow = 9,
3938
GsCheckFailed = 10,
4039
TooManyGuestFunctions = 11,
4140
FailureInDlmalloc = 12,
@@ -59,7 +58,6 @@ impl From<ErrorCode> for FbErrorCode {
5958
ErrorCode::GispatchFunctionPointerNotSet => Self::GispatchFunctionPointerNotSet,
6059
ErrorCode::OutbError => Self::OutbError,
6160
ErrorCode::UnknownError => Self::UnknownError,
62-
ErrorCode::StackOverflow => Self::StackOverflow,
6361
ErrorCode::GsCheckFailed => Self::GsCheckFailed,
6462
ErrorCode::TooManyGuestFunctions => Self::TooManyGuestFunctions,
6563
ErrorCode::FailureInDlmalloc => Self::FailureInDlmalloc,
@@ -86,7 +84,6 @@ impl From<FbErrorCode> for ErrorCode {
8684
}
8785
FbErrorCode::GispatchFunctionPointerNotSet => Self::GispatchFunctionPointerNotSet,
8886
FbErrorCode::OutbError => Self::OutbError,
89-
FbErrorCode::StackOverflow => Self::StackOverflow,
9087
FbErrorCode::GsCheckFailed => Self::GsCheckFailed,
9188
FbErrorCode::TooManyGuestFunctions => Self::TooManyGuestFunctions,
9289
FbErrorCode::FailureInDlmalloc => Self::FailureInDlmalloc,
@@ -113,7 +110,6 @@ impl From<u64> for ErrorCode {
113110
6 => Self::GispatchFunctionPointerNotSet,
114111
7 => Self::OutbError,
115112
8 => Self::UnknownError,
116-
9 => Self::StackOverflow,
117113
10 => Self::GsCheckFailed,
118114
11 => Self::TooManyGuestFunctions,
119115
12 => Self::FailureInDlmalloc,
@@ -138,7 +134,6 @@ impl From<ErrorCode> for u64 {
138134
ErrorCode::GispatchFunctionPointerNotSet => 6,
139135
ErrorCode::OutbError => 7,
140136
ErrorCode::UnknownError => 8,
141-
ErrorCode::StackOverflow => 9,
142137
ErrorCode::GsCheckFailed => 10,
143138
ErrorCode::TooManyGuestFunctions => 11,
144139
ErrorCode::FailureInDlmalloc => 12,
@@ -164,7 +159,6 @@ impl From<ErrorCode> for String {
164159
ErrorCode::GispatchFunctionPointerNotSet => "GispatchFunctionPointerNotSet".to_string(),
165160
ErrorCode::OutbError => "OutbError".to_string(),
166161
ErrorCode::UnknownError => "UnknownError".to_string(),
167-
ErrorCode::StackOverflow => "StackOverflow".to_string(),
168162
ErrorCode::GsCheckFailed => "GsCheckFailed".to_string(),
169163
ErrorCode::TooManyGuestFunctions => "TooManyGuestFunctions".to_string(),
170164
ErrorCode::FailureInDlmalloc => "FailureInDlmalloc".to_string(),

src/hyperlight_common/src/flatbuffers/hyperlight/generated/error_code_generated.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub const ENUM_MAX_ERROR_CODE: u64 = 17;
2525
note = "Use associated constants instead. This will no longer be generated in 2021."
2626
)]
2727
#[allow(non_camel_case_types)]
28-
pub const ENUM_VALUES_ERROR_CODE: [ErrorCode; 17] = [
28+
pub const ENUM_VALUES_ERROR_CODE: [ErrorCode; 16] = [
2929
ErrorCode::NoError,
3030
ErrorCode::UnsupportedParameterType,
3131
ErrorCode::GuestFunctionNameNotProvided,
@@ -34,7 +34,6 @@ pub const ENUM_VALUES_ERROR_CODE: [ErrorCode; 17] = [
3434
ErrorCode::GispatchFunctionPointerNotSet,
3535
ErrorCode::OutbError,
3636
ErrorCode::UnknownError,
37-
ErrorCode::StackOverflow,
3837
ErrorCode::GsCheckFailed,
3938
ErrorCode::TooManyGuestFunctions,
4039
ErrorCode::FailureInDlmalloc,
@@ -58,7 +57,6 @@ impl ErrorCode {
5857
pub const GispatchFunctionPointerNotSet: Self = Self(6);
5958
pub const OutbError: Self = Self(7);
6059
pub const UnknownError: Self = Self(8);
61-
pub const StackOverflow: Self = Self(9);
6260
pub const GsCheckFailed: Self = Self(10);
6361
pub const TooManyGuestFunctions: Self = Self(11);
6462
pub const FailureInDlmalloc: Self = Self(12);
@@ -79,7 +77,6 @@ impl ErrorCode {
7977
Self::GispatchFunctionPointerNotSet,
8078
Self::OutbError,
8179
Self::UnknownError,
82-
Self::StackOverflow,
8380
Self::GsCheckFailed,
8481
Self::TooManyGuestFunctions,
8582
Self::FailureInDlmalloc,
@@ -102,7 +99,6 @@ impl ErrorCode {
10299
Self::GispatchFunctionPointerNotSet => Some("GispatchFunctionPointerNotSet"),
103100
Self::OutbError => Some("OutbError"),
104101
Self::UnknownError => Some("UnknownError"),
105-
Self::StackOverflow => Some("StackOverflow"),
106102
Self::GsCheckFailed => Some("GsCheckFailed"),
107103
Self::TooManyGuestFunctions => Some("TooManyGuestFunctions"),
108104
Self::FailureInDlmalloc => Some("FailureInDlmalloc"),

src/hyperlight_common/src/layout.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ pub fn scratch_base_gpa(size: usize) -> u64 {
3232
pub fn scratch_base_gva(size: usize) -> u64 {
3333
(MAX_GVA - size + 1) as u64
3434
}
35+
36+
/// Compute the minimum scratch region size needed for a sandbox.
37+
pub use arch::min_scratch_size;

src/hyperlight_common/src/mem.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,6 @@ pub struct GuestMemoryRegion {
2828
pub ptr: u64,
2929
}
3030

31-
/// A memory region in the guest address space that is used for the stack
32-
#[derive(Debug, Clone, Copy)]
33-
#[repr(C)]
34-
pub struct GuestStack {
35-
/// The top of the user stack
36-
pub min_user_stack_address: u64,
37-
/// The user stack pointer
38-
pub user_stack_address: u64,
39-
}
40-
4131
#[derive(Debug, Clone, Copy)]
4232
#[repr(C)]
4333
pub struct HyperlightPEB {
@@ -46,5 +36,4 @@ pub struct HyperlightPEB {
4636
pub output_stack: GuestMemoryRegion,
4737
pub init_data: GuestMemoryRegion,
4838
pub guest_heap: GuestMemoryRegion,
49-
pub guest_stack: GuestStack,
5039
}

src/hyperlight_guest/src/arch/amd64/layout.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ limitations under the License.
1818
// src/hyperlight_common/src/arch/amd64/layout.rs and
1919
// src/hyperlight_guest_bin/src/arch/amd64/layout.rs
2020

21-
pub const MAIN_STACK_TOP_GVA: u64 = 0xffff_feff_ffff_f000;
21+
/// Note that the x86-64 ELF psABI requires that the stack be 16-byte
22+
/// aligned before a call instruction; we use the aligned version
23+
/// here, even though this requires adjusting the pointer by 8 bytes
24+
/// when entering the guest without a call instruction to push a
25+
/// return address.
26+
pub const MAIN_STACK_TOP_GVA: u64 = 0xffff_ff00_0000_0000;
27+
pub const MAIN_STACK_LIMIT_GVA: u64 = 0xffff_fe00_0000_0000;
2228

2329
pub fn scratch_size() -> u64 {
2430
let addr = crate::layout::scratch_size_gva();

src/hyperlight_guest/src/arch/i686/layout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
// allow compiling the guest for real mode boot scenarios.
1919

2020
pub const MAIN_STACK_TOP_GVA: usize = 0xdfff_efff;
21+
pub const MAIN_STACK_LIMIT_GVA: usize = 0xdf00_0000;
2122

2223
pub fn scratch_size() -> u64 {
2324
hyperlight_common::vmem::PAGE_SIZE as u64

src/hyperlight_guest/src/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ limitations under the License.
1818
#[cfg_attr(target_arch = "x86", path = "arch/i686/layout.rs")]
1919
mod arch;
2020

21-
pub use arch::MAIN_STACK_TOP_GVA;
21+
pub use arch::{MAIN_STACK_LIMIT_GVA, MAIN_STACK_TOP_GVA};
2222
pub fn scratch_size_gva() -> *mut u64 {
2323
use hyperlight_common::layout::{MAX_GVA, SCRATCH_TOP_SIZE_OFFSET};
2424
(MAX_GVA as u64 - SCRATCH_TOP_SIZE_OFFSET + 1) as *mut u64

0 commit comments

Comments
 (0)