Make sure VMRange fills its memory with zeros if necessary
This commit is contained in:
		
							parent
							
								
									862601604c
								
							
						
					
					
						commit
						2957fa99d5
					
				| @ -68,6 +68,7 @@ pub struct VMAllocOptions { | |||||||
|     addr: VMAddrOption, |     addr: VMAddrOption, | ||||||
|     growth: VMGrowthType, |     growth: VMGrowthType, | ||||||
|     description: String, |     description: String, | ||||||
|  |     fill_zeros: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl VMAllocOptions { | impl VMAllocOptions { | ||||||
| @ -98,6 +99,11 @@ impl VMAllocOptions { | |||||||
|         self.description = description.to_owned(); |         self.description = description.to_owned(); | ||||||
|         Ok(self) |         Ok(self) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn fill_zeros(&mut self, fill_zeros: bool) -> Result<&mut Self, Error> { | ||||||
|  |         self.fill_zeros = fill_zeros; | ||||||
|  |         Ok(self) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl fmt::Debug for VMAllocOptions { | impl fmt::Debug for VMAllocOptions { | ||||||
| @ -163,6 +169,7 @@ impl Default for VMGrowthType { | |||||||
| pub struct VMResizeOptions { | pub struct VMResizeOptions { | ||||||
|     new_size: usize, |     new_size: usize, | ||||||
|     new_addr: VMAddrOption, |     new_addr: VMAddrOption, | ||||||
|  |     fill_zeros: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl VMResizeOptions { | impl VMResizeOptions { | ||||||
| @ -180,4 +187,9 @@ impl VMResizeOptions { | |||||||
|         self.new_addr = new_addr; |         self.new_addr = new_addr; | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn fill_zeros(&mut self, fill_zeros: bool) -> &mut Self { | ||||||
|  |         self.fill_zeros = fill_zeros; | ||||||
|  |         self | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -90,11 +90,12 @@ impl ProcessVM { | |||||||
|     ) -> Result<(VMArea, VMArea, VMArea, VMArea), Error> { |     ) -> Result<(VMArea, VMArea, VMArea, VMArea), Error> { | ||||||
|         let mut addr = data_domain.get_start(); |         let mut addr = data_domain.get_start(); | ||||||
|         let mut alloc_vma_continuously = |         let mut alloc_vma_continuously = | ||||||
|             |addr: &mut usize, size, flags, growth, desc| -> Result<_, Error> { |             |addr: &mut usize, desc, size, flags, growth, fill_zeros| -> Result<_, Error> { | ||||||
|                 let mut options = VMAllocOptions::new(size)?; |                 let mut options = VMAllocOptions::new(size)?; | ||||||
|                 options.addr(VMAddrOption::Fixed(*addr))? |                 options.addr(VMAddrOption::Fixed(*addr))? | ||||||
|                     .growth(growth)? |                     .growth(growth)? | ||||||
|                     .description(desc)?; |                     .description(desc)? | ||||||
|  |                     .fill_zeros(fill_zeros)?; | ||||||
|                 let new_vma = data_domain.alloc_area(&options, flags)?; |                 let new_vma = data_domain.alloc_area(&options, flags)?; | ||||||
|                 *addr += size; |                 *addr += size; | ||||||
|                 Ok(new_vma) |                 Ok(new_vma) | ||||||
| @ -103,14 +104,17 @@ impl ProcessVM { | |||||||
|         let rx_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_X); |         let rx_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_X); | ||||||
|         let rw_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_W); |         let rw_flags = VMAreaFlags(VM_AREA_FLAG_R | VM_AREA_FLAG_W); | ||||||
| 
 | 
 | ||||||
|         let code_vma = alloc_vma_continuously(&mut addr, code_size, rx_flags, VMGrowthType::Fixed, "code_vma")?; |         let code_vma = alloc_vma_continuously(&mut addr, "code_vma", code_size, | ||||||
|         let data_vma = alloc_vma_continuously(&mut addr, data_size, rw_flags, VMGrowthType::Fixed, "data_vma")?; |                                               rx_flags, VMGrowthType::Fixed, true)?; | ||||||
|         let heap_vma = alloc_vma_continuously(&mut addr, 0, rw_flags, VMGrowthType::Upward, "heap_vma")?; |         let data_vma = alloc_vma_continuously(&mut addr, "data_vma", data_size, | ||||||
|  |                                               rw_flags, VMGrowthType::Fixed, true)?; | ||||||
|  |         let heap_vma = alloc_vma_continuously(&mut addr, "heap_vma", 0, | ||||||
|  |                                               rw_flags, VMGrowthType::Upward, true)?; | ||||||
|         // Preserve the space for heap
 |         // Preserve the space for heap
 | ||||||
|         addr += heap_size; |         addr += heap_size; | ||||||
|         // After the heap is the stack
 |         // After the heap is the stack
 | ||||||
|         let stack_vma = |         let stack_vma = alloc_vma_continuously(&mut addr, "stack_vma", stack_size, | ||||||
|             alloc_vma_continuously(&mut addr, stack_size, rw_flags, VMGrowthType::Downward, "stack_vma")?; |                                                rw_flags, VMGrowthType::Downward, false)?; | ||||||
|         Ok((code_vma, data_vma, heap_vma, stack_vma)) |         Ok((code_vma, data_vma, heap_vma, stack_vma)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -191,7 +195,7 @@ impl ProcessVM { | |||||||
|                 .iter() |                 .iter() | ||||||
|                 .position(|vma| vma.get_start() == addr && vma.get_end() == addr + size); |                 .position(|vma| vma.get_start() == addr && vma.get_end() == addr + size); | ||||||
|             if mmap_vma_i.is_none() { |             if mmap_vma_i.is_none() { | ||||||
|                 return Ok(()); |                 return errno!(EINVAL, "memory area not found"); | ||||||
|             } |             } | ||||||
|             mmap_vma_i.unwrap() |             mmap_vma_i.unwrap() | ||||||
|         }; |         }; | ||||||
| @ -221,12 +225,12 @@ impl ProcessVM { | |||||||
|         } else if new_brk < heap_start { |         } else if new_brk < heap_start { | ||||||
|             return errno!(EINVAL, "New brk address is too low"); |             return errno!(EINVAL, "New brk address is too low"); | ||||||
|         } else if new_brk > heap_end { |         } else if new_brk > heap_end { | ||||||
|             // TODO: init the memory with zeros for the expanded area
 |  | ||||||
|             let resize_options = { |             let resize_options = { | ||||||
|                 let new_heap_end = align_up(new_brk, 4096); |                 let new_heap_end = align_up(new_brk, PAGE_SIZE); | ||||||
|                 let new_heap_size = new_heap_end - heap_start; |                 let new_heap_size = new_heap_end - heap_start; | ||||||
|                 let mut options = VMResizeOptions::new(new_heap_size)?; |                 let mut options = VMResizeOptions::new(new_heap_size)?; | ||||||
|                 options.addr(VMAddrOption::Fixed(heap_start)); |                 options.addr(VMAddrOption::Fixed(heap_start)) | ||||||
|  |                     .fill_zeros(true); | ||||||
|                 options |                 options | ||||||
|             }; |             }; | ||||||
|             let heap_vma = self.heap_vma.as_mut().unwrap(); |             let heap_vma = self.heap_vma.as_mut().unwrap(); | ||||||
|  | |||||||
| @ -59,14 +59,6 @@ impl VMDomain { | |||||||
|         flags: VMAreaFlags, |         flags: VMAreaFlags, | ||||||
|     ) -> Result<VMArea, Error> { |     ) -> Result<VMArea, Error> { | ||||||
|         let new_range = self.range.alloc_subrange(options)?; |         let new_range = self.range.alloc_subrange(options)?; | ||||||
| 
 |  | ||||||
|         // Init the memory area with all zeros
 |  | ||||||
|         unsafe { |  | ||||||
|             let mem_ptr = new_range.get_start() as *mut c_void; |  | ||||||
|             let mem_size = new_range.get_size() as size_t; |  | ||||||
|             memset(mem_ptr, 0 as c_int, mem_size); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Ok(VMArea { |         Ok(VMArea { | ||||||
|             range: new_range, |             range: new_range, | ||||||
|             flags: flags, |             flags: flags, | ||||||
| @ -82,16 +74,10 @@ impl VMDomain { | |||||||
|         area: &mut VMArea, |         area: &mut VMArea, | ||||||
|         options: &VMResizeOptions, |         options: &VMResizeOptions, | ||||||
|     ) -> Result<(), Error> { |     ) -> Result<(), Error> { | ||||||
|         // TODO: init memory with zeros when expanding!
 |  | ||||||
|         self.range.resize_subrange(&mut area.range, options) |         self.range.resize_subrange(&mut area.range, options) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[link(name = "sgx_tstdc")] |  | ||||||
| extern "C" { |  | ||||||
|     pub fn memset(p: *mut c_void, c: c_int, n: size_t) -> *mut c_void; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct VMArea { | pub struct VMArea { | ||||||
|  | |||||||
| @ -81,6 +81,15 @@ impl VMRange { | |||||||
|         self.get_subranges_mut() |         self.get_subranges_mut() | ||||||
|             .insert(new_subrange_idx, new_subrange_inner); |             .insert(new_subrange_idx, new_subrange_inner); | ||||||
| 
 | 
 | ||||||
|  |         if options.fill_zeros { | ||||||
|  |             // Init the memory area with all zeros
 | ||||||
|  |             unsafe { | ||||||
|  |                 let mem_ptr = new_subrange_inner.get_start() as *mut c_void; | ||||||
|  |                 let mem_size = new_subrange_inner.get_size() as size_t; | ||||||
|  |                 memset(mem_ptr, 0 as c_int, mem_size); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // Although there are two copies of the newly created VMRangeInner obj,
 |         // Although there are two copies of the newly created VMRangeInner obj,
 | ||||||
|         // we can keep them in sync as all mutation on VMRange object must
 |         // we can keep them in sync as all mutation on VMRange object must
 | ||||||
|         // be carried out through dealloc_subrange() and resize_subrange() that
 |         // be carried out through dealloc_subrange() and resize_subrange() that
 | ||||||
| @ -140,7 +149,7 @@ impl VMRange { | |||||||
|         } |         } | ||||||
|         // Grow
 |         // Grow
 | ||||||
|         else { |         else { | ||||||
|             self.grow_subrange_to(subrange, new_size) |             self.grow_subrange_to(subrange, new_size, options.fill_zeros) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -340,39 +349,58 @@ impl VMRange { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn grow_subrange_to(&mut self, subrange: &mut VMRange, new_size: usize) -> Result<(), Error> { |     fn grow_subrange_to(&mut self, subrange: &mut VMRange, new_size: usize, fill_zeros: bool) -> Result<(), Error> { | ||||||
|         let subrange_i = self.position_subrange(subrange); |         let subrange_i = self.position_subrange(subrange); | ||||||
|         let subranges = self.get_subranges_mut(); |         let subranges = self.get_subranges_mut(); | ||||||
| 
 | 
 | ||||||
|  |         let subrange_old_start = subrange.inner.start; | ||||||
|  |         let subrange_old_end = subrange.inner.end; | ||||||
|  |         let subrange_old_size = subrange.get_size(); | ||||||
|  | 
 | ||||||
|         if subrange.inner.growth == VMGrowthType::Upward { |         if subrange.inner.growth == VMGrowthType::Upward { | ||||||
|             // Can we grow?
 |             // Can we grow upward?
 | ||||||
|             let max_new_size = { |             let max_new_size = { | ||||||
|                 let next_subrange = &subranges[subrange_i + 1]; |                 let next_subrange = &subranges[subrange_i + 1]; | ||||||
|                 next_subrange.start - subrange.inner.start |                 next_subrange.start - subrange_old_start | ||||||
|             }; |             }; | ||||||
|             if new_size > max_new_size { |             if new_size > max_new_size { | ||||||
|                 return errno!(ENOMEM, "Cannot grow to new size"); |                 return errno!(ENOMEM, "Cannot grow to new size"); | ||||||
|             } |             } | ||||||
|             // Do grow
 |             // Do grow
 | ||||||
|             let subrange_new_end = subrange.inner.start + new_size; |             let subrange_new_end = subrange_old_start + new_size; | ||||||
|             subrange.inner.end = subrange_new_end; |             subrange.inner.end = subrange_new_end; | ||||||
|             // Sync state
 |             // Sync state
 | ||||||
|             subranges[subrange_i].end = subrange_new_end; |             subranges[subrange_i].end = subrange_new_end; | ||||||
|         } else { |             // Init memory
 | ||||||
|             // self.growth == VMGrowthType::Downward
 |             if fill_zeros { | ||||||
|             // Can we grow?
 |                 unsafe { | ||||||
|  |                     let mem_ptr = subrange_old_end as *mut c_void; | ||||||
|  |                     let mem_size = (subrange_new_end - subrange_old_end) as size_t; | ||||||
|  |                     memset(mem_ptr, 0 as c_int, mem_size); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else { // self.growth == VMGrowthType::Downward
 | ||||||
|  |             // Can we grow downard?
 | ||||||
|             let max_new_size = { |             let max_new_size = { | ||||||
|                 let pre_subrange = &subranges[subrange_i - 1]; |                 let pre_subrange = &subranges[subrange_i - 1]; | ||||||
|                 subrange.inner.end - pre_subrange.end |                 subrange_old_end - pre_subrange.end | ||||||
|             }; |             }; | ||||||
|             if new_size > max_new_size { |             if new_size > max_new_size { | ||||||
|                 return errno!(ENOMEM, "Cannot grow to new size"); |                 return errno!(ENOMEM, "Cannot grow to new size"); | ||||||
|             } |             } | ||||||
|             // Do grow
 |             // Do grow
 | ||||||
|             let subrange_new_start = subrange.inner.end - new_size; |             let subrange_new_start = subrange_old_end - new_size; | ||||||
|             subrange.inner.start = subrange_new_start; |             subrange.inner.start = subrange_new_start; | ||||||
|             // Sync state
 |             // Sync state
 | ||||||
|             subranges[subrange_i].start = subrange_new_start; |             subranges[subrange_i].start = subrange_new_start; | ||||||
|  |             // Init memory
 | ||||||
|  |             if fill_zeros { | ||||||
|  |                 unsafe { | ||||||
|  |                     let mem_ptr = subrange_new_start as *mut c_void; | ||||||
|  |                     let mem_size = (subrange_old_start - subrange_new_start) as size_t; | ||||||
|  |                     memset(mem_ptr, 0 as c_int, mem_size); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| @ -532,3 +560,8 @@ impl PartialOrd for FreeSpace { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | #[link(name = "sgx_tstdc")] | ||||||
|  | extern "C" { | ||||||
|  |     pub fn memset(p: *mut c_void, c: c_int, n: size_t) -> *mut c_void; | ||||||
|  | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user