@@ -21,15 +21,20 @@ use rand::{RngCore, rng};
21
21
use tracing:: { Span , instrument} ;
22
22
23
23
use super :: memory_region:: MemoryRegionType :: {
24
- Code , GuardPage , Heap , HostFunctionDefinitions , InputData , OutputData , PageTables , Peb , Stack ,
24
+ Code , GuardPage , Heap , HostFunctionDefinitions , InitData , InputData , OutputData , PageTables ,
25
+ Peb , Stack ,
26
+ } ;
27
+ use super :: memory_region:: {
28
+ DEFAULT_GUEST_BLOB_MEM_FLAGS , MemoryRegion , MemoryRegionFlags , MemoryRegionVecBuilder ,
25
29
} ;
26
- use super :: memory_region:: { MemoryRegion , MemoryRegionFlags , MemoryRegionVecBuilder } ;
27
30
use super :: mgr:: AMOUNT_OF_MEMORY_PER_PT ;
28
31
use super :: shared_mem:: { ExclusiveSharedMemory , GuestSharedMemory , SharedMemory } ;
29
32
use crate :: error:: HyperlightError :: { GuestOffsetIsInvalid , MemoryRequestTooBig } ;
30
33
use crate :: sandbox:: SandboxConfiguration ;
31
34
use crate :: { Result , new_error} ;
32
35
36
+ // +-------------------------------------------+
37
+ // | Init Data | (GuestBlob size)
33
38
// +-------------------------------------------+
34
39
// | Guest (User) Stack |
35
40
// +-------------------------------------------+
@@ -56,6 +61,8 @@ use crate::{Result, new_error};
56
61
// | PML4 |
57
62
// +-------------------------------------------+ 0x0_000
58
63
64
+ /// - `InitData` - some extra data that can be loaded onto the sandbox during
65
+ /// initialization.
59
66
///
60
67
/// - `HostDefinitions` - the length of this is the `HostFunctionDefinitionSize`
61
68
/// field from `SandboxConfiguration`
@@ -82,6 +89,7 @@ pub(crate) struct SandboxMemoryLayout {
82
89
pub ( super ) stack_size : usize ,
83
90
/// The heap size of this sandbox.
84
91
pub ( super ) heap_size : usize ,
92
+ init_data_size : usize ,
85
93
86
94
/// The following fields are offsets to the actual PEB struct fields.
87
95
/// They are used when writing the PEB struct itself
@@ -103,6 +111,7 @@ pub(crate) struct SandboxMemoryLayout {
103
111
guest_heap_buffer_offset : usize ,
104
112
guard_page_offset : usize ,
105
113
guest_user_stack_buffer_offset : usize , // the lowest address of the user stack
114
+ init_data_offset : usize ,
106
115
107
116
// other
108
117
pub ( crate ) peb_address : usize ,
@@ -111,6 +120,7 @@ pub(crate) struct SandboxMemoryLayout {
111
120
total_page_table_size : usize ,
112
121
// The offset in the sandbox memory where the code starts
113
122
guest_code_offset : usize ,
123
+ pub ( crate ) init_data_permissions : Option < MemoryRegionFlags > ,
114
124
}
115
125
116
126
impl Debug for SandboxMemoryLayout {
@@ -122,6 +132,10 @@ impl Debug for SandboxMemoryLayout {
122
132
)
123
133
. field ( "Stack Size" , & format_args ! ( "{:#x}" , self . stack_size) )
124
134
. field ( "Heap Size" , & format_args ! ( "{:#x}" , self . heap_size) )
135
+ . field (
136
+ "Init Data Size" ,
137
+ & format_args ! ( "{:#x}" , self . init_data_size) ,
138
+ )
125
139
. field ( "PEB Address" , & format_args ! ( "{:#x}" , self . peb_address) )
126
140
. field ( "PEB Offset" , & format_args ! ( "{:#x}" , self . peb_offset) )
127
141
. field ( "Code Size" , & format_args ! ( "{:#x}" , self . code_size) )
@@ -181,6 +195,10 @@ impl Debug for SandboxMemoryLayout {
181
195
"Guest User Stack Buffer Offset" ,
182
196
& format_args ! ( "{:#x}" , self . guest_user_stack_buffer_offset) ,
183
197
)
198
+ . field (
199
+ "Init Data Offset" ,
200
+ & format_args ! ( "{:#x}" , self . init_data_offset) ,
201
+ )
184
202
. field (
185
203
"Page Table Size" ,
186
204
& format_args ! ( "{:#x}" , self . total_page_table_size) ,
@@ -231,6 +249,8 @@ impl SandboxMemoryLayout {
231
249
code_size : usize ,
232
250
stack_size : usize ,
233
251
heap_size : usize ,
252
+ init_data_size : usize ,
253
+ init_data_permissions : Option < MemoryRegionFlags > ,
234
254
) -> Result < Self > {
235
255
let total_page_table_size =
236
256
Self :: get_total_page_table_size ( cfg, code_size, stack_size, heap_size) ;
@@ -275,6 +295,7 @@ impl SandboxMemoryLayout {
275
295
let guest_user_stack_buffer_offset = guard_page_offset + PAGE_SIZE_USIZE ;
276
296
// round up stack size to page size. This is needed for MemoryRegion
277
297
let stack_size_rounded = round_up_to ( stack_size, PAGE_SIZE_USIZE ) ;
298
+ let init_data_offset = guest_user_stack_buffer_offset + stack_size_rounded;
278
299
279
300
Ok ( Self {
280
301
peb_offset,
@@ -299,6 +320,9 @@ impl SandboxMemoryLayout {
299
320
guard_page_offset,
300
321
total_page_table_size,
301
322
guest_code_offset,
323
+ init_data_offset,
324
+ init_data_size,
325
+ init_data_permissions,
302
326
} )
303
327
}
304
328
@@ -444,7 +468,7 @@ impl SandboxMemoryLayout {
444
468
/// layout.
445
469
#[ instrument( skip_all, parent = Span :: current( ) , level= "Trace" ) ]
446
470
fn get_unaligned_memory_size ( & self ) -> usize {
447
- self . get_top_of_user_stack_offset ( ) + self . stack_size
471
+ self . init_data_offset + self . init_data_size
448
472
}
449
473
450
474
/// get the code offset
@@ -682,12 +706,31 @@ impl SandboxMemoryLayout {
682
706
}
683
707
684
708
// stack
685
- let final_offset = builder. push_page_aligned (
709
+ let init_data_offset = builder. push_page_aligned (
686
710
self . get_guest_stack_size ( ) ,
687
711
MemoryRegionFlags :: READ | MemoryRegionFlags :: WRITE ,
688
712
Stack ,
689
713
) ;
690
714
715
+ let expected_init_data_offset = TryInto :: < usize > :: try_into ( self . init_data_offset ) ?;
716
+
717
+ if init_data_offset != expected_init_data_offset {
718
+ return Err ( new_error ! (
719
+ "Init Data offset does not match expected Init Data offset expected: {}, actual: {}" ,
720
+ expected_init_data_offset,
721
+ init_data_offset
722
+ ) ) ;
723
+ }
724
+
725
+ let final_offset = if self . init_data_size > 0 {
726
+ let mem_flags = self
727
+ . init_data_permissions
728
+ . unwrap_or ( DEFAULT_GUEST_BLOB_MEM_FLAGS ) ;
729
+ builder. push_page_aligned ( self . init_data_size , mem_flags, InitData )
730
+ } else {
731
+ init_data_offset
732
+ } ;
733
+
691
734
let expected_final_offset = TryInto :: < usize > :: try_into ( self . get_memory_size ( ) ?) ?;
692
735
693
736
if final_offset != expected_final_offset {
@@ -701,6 +744,16 @@ impl SandboxMemoryLayout {
701
744
Ok ( builder. build ( ) )
702
745
}
703
746
747
+ #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level= "Trace" ) ]
748
+ pub ( crate ) fn write_init_data (
749
+ & self ,
750
+ shared_mem : & mut ExclusiveSharedMemory ,
751
+ bytes : & [ u8 ] ,
752
+ ) -> Result < ( ) > {
753
+ shared_mem. copy_from_slice ( bytes, self . init_data_offset ) ?;
754
+ Ok ( ( ) )
755
+ }
756
+
704
757
/// Write the finished memory layout to `shared_mem` and return
705
758
/// `Ok` if successful.
706
759
///
@@ -869,7 +922,8 @@ mod tests {
869
922
#[ test]
870
923
fn test_get_memory_size ( ) {
871
924
let sbox_cfg = SandboxConfiguration :: default ( ) ;
872
- let sbox_mem_layout = SandboxMemoryLayout :: new ( sbox_cfg, 4096 , 2048 , 4096 ) . unwrap ( ) ;
925
+ let sbox_mem_layout =
926
+ SandboxMemoryLayout :: new ( sbox_cfg, 4096 , 2048 , 4096 , 0 , None ) . unwrap ( ) ;
873
927
assert_eq ! (
874
928
sbox_mem_layout. get_memory_size( ) . unwrap( ) ,
875
929
get_expected_memory_size( & sbox_mem_layout)
0 commit comments