From 997c21a45f0f0686caa0c96ca126347680532dd9 Mon Sep 17 00:00:00 2001 From: "Hui, Chunyang" Date: Tue, 27 Dec 2022 11:58:10 +0800 Subject: [PATCH] Fix reserved memory permission for EDMM support --- src/libos/src/vm/user_space_vm.rs | 19 +++----------- src/libos/src/vm/vm_perms.rs | 43 ++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/libos/src/vm/user_space_vm.rs b/src/libos/src/vm/user_space_vm.rs index bef93a18..4a04ac87 100644 --- a/src/libos/src/vm/user_space_vm.rs +++ b/src/libos/src/vm/user_space_vm.rs @@ -23,11 +23,9 @@ impl UserSpaceVMManager { if ptr.is_null() { return_errno!(ENOMEM, "run out of reserved memory"); } - // Change the page permission to RW (default) - assert!( - sgx_tprotect_rsrv_mem(ptr, rsrv_mem_size, RSRV_MEM_PERM.bits()) - == sgx_status_t::SGX_SUCCESS - ); + + // Without EDMM support and the ReservedMemExecutable is set to 1, the reserved memory will be RWX. And we can't change the reserved memory permission. + // With EDMM support, the reserved memory permission is RW by default. And we can change the permissions when needed. let addr = ptr as usize; debug!( @@ -99,15 +97,4 @@ extern "C" { // Return: 0 on success; otherwise -1 // fn sgx_free_rsrv_mem(addr: *const c_void, length: usize) -> i32; - - // Modify the access permissions of the pages in the reserved memory area - // - // Parameters: - // Inputs: addr[in]: Starting address of region which needs to change access - // permission. Page aligned. - // length[in]: The length of the memory to be manipulated in bytes. Page aligned. - // prot[in]: The target memory protection. - // Return: sgx_status_t - // - fn sgx_tprotect_rsrv_mem(addr: *const c_void, length: usize, prot: i32) -> sgx_status_t; } diff --git a/src/libos/src/vm/vm_perms.rs b/src/libos/src/vm/vm_perms.rs index 89e0fde7..f092dd08 100644 --- a/src/libos/src/vm/vm_perms.rs +++ b/src/libos/src/vm/vm_perms.rs @@ -34,14 +34,7 @@ impl VMPerms { } pub fn apply_perms(protect_range: &VMRange, perms: VMPerms) { - extern "C" { - pub fn occlum_ocall_mprotect( - retval: *mut i32, - addr: *const c_void, - len: usize, - prot: i32, - ) -> sgx_status_t; - }; + use sgx_trts::enclave::rsgx_is_supported_EDMM; unsafe { let mut retval = 0; @@ -51,8 +44,18 @@ impl VMPerms { // Since the memory are managed by our own, mprotect ocall shouldn't use this flag. Otherwise, EINVAL will be thrown. let mut prot = perms.clone(); prot.remove(VMPerms::GROWSDOWN); - let sgx_status = occlum_ocall_mprotect(&mut retval, addr, len, prot.bits() as i32); - assert!(sgx_status == sgx_status_t::SGX_SUCCESS && retval == 0); + + if rsgx_is_supported_EDMM() { + // With EDMM support, reserved memory permission should be updated. + assert!( + sgx_tprotect_rsrv_mem(addr, len, prot.bits() as i32) + == sgx_status_t::SGX_SUCCESS + ); + } else { + // Without EDMM support, reserved memory permission is statically RWX and we only need to do mprotect ocall. + let sgx_status = occlum_ocall_mprotect(&mut retval, addr, len, prot.bits() as i32); + assert!(sgx_status == sgx_status_t::SGX_SUCCESS && retval == 0); + } } } @@ -82,3 +85,23 @@ impl Default for VMPerms { VMPerms::DEFAULT } } + +extern "C" { + // Modify the access permissions of the pages in the reserved memory area + // + // Parameters: + // Inputs: addr[in]: Starting address of region which needs to change access + // permission. Page aligned. + // length[in]: The length of the memory to be manipulated in bytes. Page aligned. + // prot[in]: The target memory protection. + // Return: sgx_status_t + // + fn sgx_tprotect_rsrv_mem(addr: *const c_void, length: usize, prot: i32) -> sgx_status_t; + + fn occlum_ocall_mprotect( + retval: *mut i32, + addr: *const c_void, + len: usize, + prot: i32, + ) -> sgx_status_t; +}