diff --git a/common/inc/internal/global_data.h b/common/inc/internal/global_data.h index 0d59ee33..c6032841 100644 --- a/common/inc/internal/global_data.h +++ b/common/inc/internal/global_data.h @@ -61,7 +61,8 @@ typedef struct _global_data_t uint32_t layout_entry_num; uint32_t reserved; layout_t layout_table[LAYOUT_ENTRY_NUM]; - uint64_t enclave_start_address; + uint64_t enclave_image_address; + uint64_t elrange_start_address; uint64_t elrange_size; } global_data_t; diff --git a/common/inc/internal/metadata.h b/common/inc/internal/metadata.h index 8c727a59..b23e14ae 100644 --- a/common/inc/internal/metadata.h +++ b/common/inc/internal/metadata.h @@ -183,8 +183,9 @@ typedef struct _metadata_t sgx_attributes_t attributes; /* XFeatureMask to be set in SECS. */ enclave_css_t enclave_css; /* The enclave signature */ data_directory_t dirs[DIR_NUM]; - uint8_t data[18576]; - uint64_t enclave_start_address; + uint8_t data[18568]; + uint64_t enclave_image_address; + uint64_t elrange_start_address; uint64_t elrange_size; }metadata_t; diff --git a/common/inc/internal/se_debugger_lib.h b/common/inc/internal/se_debugger_lib.h index 5d2f16af..d76a3f39 100644 --- a/common/inc/internal/se_debugger_lib.h +++ b/common/inc/internal/se_debugger_lib.h @@ -87,6 +87,8 @@ typedef struct _debug_enclave_info_t PADDED_POINTER(void, lpFileName); PADDED_POINTER(void, g_peak_heap_used_addr); PADDED_POINTER(void, g_peak_rsrv_mem_committed_addr); + uint64_t elrange_start_address; + uint64_t elrange_size; PADDED_POINTER(void, dyn_sec); sgx_misc_select_t misc_select; /* The following members are optional or unused */ diff --git a/psw/enclave_common/sgx_enclave_common.cpp b/psw/enclave_common/sgx_enclave_common.cpp index 3bfbef3f..cad23930 100644 --- a/psw/enclave_common/sgx_enclave_common.cpp +++ b/psw/enclave_common/sgx_enclave_common.cpp @@ -56,10 +56,10 @@ func_get_launch_token_t get_launch_token_func = NULL; static void* s_hdlopen = NULL; -static se_mutex_t s_dlopen_mutex; +static Mutex s_dlopen_mutex; -static se_mutex_t s_device_mutex; -static se_mutex_t s_enclave_mutex; +static Mutex s_device_mutex; +static Mutex s_enclave_mutex; static Mutex s_enclave_info_mutex; @@ -71,9 +71,7 @@ static std::map s_hfile; //enclave file handles for drive static std::map s_enclave_size; static std::map s_enclave_init; static std::map s_secs_attr; -std::maps_enclave_elrange_map; - - +static std::maps_enclave_elrange_map; typedef struct _mem_region_t { void* addr; @@ -88,58 +86,46 @@ extern "C" bool open_file(int *hFile) if (hFile == NULL) return false; - se_mutex_lock(&s_device_mutex); + LockGuard lock(&s_device_mutex); if (s_driver_type != SGX_DRIVER_IN_KERNEL) { - se_mutex_unlock(&s_device_mutex); return false; } if (true == open_se_device(SGX_DRIVER_IN_KERNEL, hFile)) { - se_mutex_unlock(&s_device_mutex); return true; } - se_mutex_unlock(&s_device_mutex); - return false; } extern "C" void close_file(int *hFile) { - se_mutex_lock(&s_device_mutex); - + LockGuard lock(&s_device_mutex); close_se_device(hFile); - - se_mutex_unlock(&s_device_mutex); } extern "C" bool open_device(void) { - se_mutex_lock(&s_device_mutex); + LockGuard lock(&s_device_mutex); if (s_hdevice != -1) { - se_mutex_unlock(&s_device_mutex); return true; } if (true == open_se_device(s_driver_type, &s_hdevice)) { - se_mutex_unlock(&s_device_mutex); return true; } s_hdevice = -1; - se_mutex_unlock(&s_device_mutex); return false; } extern "C" void close_device(void) { - se_mutex_lock(&s_device_mutex); + LockGuard lock(&s_device_mutex); close_se_device(&s_hdevice); s_driver_type = SGX_DRIVER_UNKNOWN; //this may not be needed - can it change on the platform? - - se_mutex_unlock(&s_device_mutex); } extern "C" int get_file_handle_from_address(void* target_address) @@ -147,7 +133,7 @@ extern "C" int get_file_handle_from_address(void* target_address) int hfile = -1; //find the enclave file handle from the target address - se_mutex_lock(&s_enclave_mutex); + LockGuard lock(&s_enclave_mutex); for (auto rec : s_enclave_size) { if ((uint64_t)target_address >= (uint64_t)rec.first && (uint64_t)target_address < (uint64_t)rec.first + (uint64_t)rec.second) { @@ -158,7 +144,6 @@ extern "C" int get_file_handle_from_address(void* target_address) break; } } - se_mutex_unlock(&s_enclave_mutex); return hfile; } @@ -168,7 +153,7 @@ extern "C" void* get_enclave_base_address_from_address(void* target_address) void* base_addr = NULL; //find the enclave file handle from the target address - se_mutex_lock(&s_enclave_mutex); + LockGuard lock(&s_enclave_mutex); for (auto rec : s_enclave_size) { if ((uint64_t)target_address >= (uint64_t)rec.first && (uint64_t)target_address < (uint64_t)rec.first + (uint64_t)rec.second) { @@ -176,32 +161,45 @@ extern "C" void* get_enclave_base_address_from_address(void* target_address) break; } } - se_mutex_unlock(&s_enclave_mutex); return base_addr; } +extern "C" bool get_elrange_from_base_address(void* base_address, enclave_elrange_t* enclave_elrange) +{ + LockGuard lock(&s_enclave_info_mutex); + if(s_enclave_elrange_map.count(base_address) != 0) + { + if(enclave_elrange != NULL) + { + enclave_elrange->elrange_size = s_enclave_elrange_map[base_address]->elrange_size; + enclave_elrange->elrange_start_address = s_enclave_elrange_map[base_address]->elrange_start_address; + enclave_elrange->enclave_image_address = s_enclave_elrange_map[base_address]->enclave_image_address; + } + return true; + } + + return false; +} + static func_get_launch_token_t get_launch_token_function(void) { if (get_launch_token_func == NULL) { - se_mutex_lock(&s_dlopen_mutex); + LockGuard lock(&s_dlopen_mutex); if (get_launch_token_func != NULL) { - se_mutex_unlock(&s_dlopen_mutex); return get_launch_token_func; } if (s_hdlopen == NULL) { s_hdlopen = dlopen(SGX_LAUNCH_SO, RTLD_LAZY); if (s_hdlopen == NULL) { - se_mutex_unlock(&s_dlopen_mutex); return NULL; } } get_launch_token_func = (func_get_launch_token_t)dlsym(s_hdlopen, SGX_GET_LAUNCH_TOKEN); - se_mutex_unlock(&s_dlopen_mutex); } return get_launch_token_func; @@ -209,20 +207,14 @@ static func_get_launch_token_t get_launch_token_function(void) static void close_sofile(void) { - se_mutex_lock(&s_dlopen_mutex); + LockGuard lock(&s_dlopen_mutex); if (s_hdlopen != NULL) { dlclose(s_hdlopen); s_hdlopen = NULL; } - se_mutex_unlock(&s_dlopen_mutex); } -static void __attribute__((constructor)) enclave_init(void) -{ - se_mutex_init(&s_device_mutex); - se_mutex_init(&s_dlopen_mutex); - se_mutex_init(&s_enclave_mutex); -} + static void release_enclave_elrange_map() { for (auto &res:s_enclave_elrange_map) @@ -236,9 +228,6 @@ static void __attribute__((destructor)) enclave_fini(void) { close_device(); close_sofile(); - se_mutex_destroy(&s_device_mutex); - se_mutex_destroy(&s_dlopen_mutex); - se_mutex_destroy(&s_enclave_mutex); release_enclave_elrange_map(); } @@ -354,6 +343,9 @@ extern "C" void* COMM_API enclave_create( int hdevice_temp = -1; size_t enclave_size = virtual_size; void* enclave_base = NULL; + enclave_elrange_t enclave_elrange; + + memset(&enclave_elrange, 0, sizeof(enclave_elrange)); if ((type != ENCLAVE_TYPE_SGX1 && type != ENCLAVE_TYPE_SGX2) || info == NULL) { if (enclave_error != NULL) @@ -399,8 +391,8 @@ extern "C" void* COMM_API enclave_create( //The in-kernel driver does not do the base and size alignment. This is up to user mode to do it. //Therefore enclave_size will be virtual_size*2. The unused region will be released by calling munmap later. enclave_size = virtual_size*2; - //for this suitation, we don't need to make the base and size alignement - if(s_enclave_elrange_map.count(base_address) != 0 && s_enclave_elrange_map[base_address]->elrange_size!= 0) + //for this situation, we don't need to make the base and size alignement + if(get_elrange_from_base_address(base_address, NULL) == true) { enclave_size = virtual_size; } @@ -409,19 +401,22 @@ extern "C" void* COMM_API enclave_create( { hdevice_temp = s_hdevice; } + + int mmap_flag = 0; + if(get_elrange_from_base_address(base_address, NULL) == true) + { + mmap_flag |= MAP_FIXED; + } if(s_driver_type == SGX_DRIVER_IN_KERNEL) { - int mmap_flag = MAP_PRIVATE | MAP_ANONYMOUS; - if(base_address != NULL) - { - mmap_flag |= MAP_FIXED; - } + mmap_flag |= MAP_PRIVATE | MAP_ANONYMOUS; enclave_base = mmap(base_address, enclave_size, PROT_NONE, mmap_flag, -1, 0); } else { - enclave_base = mmap(base_address, enclave_size, PROT_NONE, MAP_SHARED, hdevice_temp, 0); + mmap_flag |= MAP_SHARED; + enclave_base = mmap(base_address, enclave_size, PROT_NONE, mmap_flag, hdevice_temp, 0); } if (enclave_base == MAP_FAILED) { @@ -435,7 +430,7 @@ extern "C" void* COMM_API enclave_create( return NULL; } - if(s_driver_type == SGX_DRIVER_IN_KERNEL && s_enclave_elrange_map.count(base_address) == 0) + if(s_driver_type == SGX_DRIVER_IN_KERNEL && get_elrange_from_base_address(base_address, NULL) == false) { uint64_t aligned_addr = ((uint64_t)enclave_base + virtual_size - 1) & ~(virtual_size - 1); if(aligned_addr != (uint64_t)enclave_base) @@ -469,17 +464,18 @@ extern "C" void* COMM_API enclave_create( } } enclave_base = (void*)aligned_addr; - } - if(s_enclave_elrange_map.count(base_address) != 0 && s_enclave_elrange_map[base_address]->elrange_size!= 0) + + if(get_elrange_from_base_address(base_address, &enclave_elrange)) { - secs->base = 0; - secs->size = s_enclave_elrange_map[base_address]->elrange_size; + secs->base = reinterpret_cast(enclave_elrange.elrange_start_address); + secs->size = enclave_elrange.elrange_size; } else { secs->base = enclave_base; } + struct sgx_enclave_create param = { 0 }; param.src = POINTER_TO_U64(secs); @@ -550,7 +546,7 @@ extern "C" void* COMM_API enclave_create( } - se_mutex_lock(&s_enclave_mutex); + LockGuard lock(&s_enclave_mutex); //if in-kernel driver then save the file handle if (s_driver_type == SGX_DRIVER_IN_KERNEL) @@ -567,14 +563,88 @@ extern "C" void* COMM_API enclave_create( s_enclave_mem_region[enclave_base].addr = 0; s_enclave_mem_region[enclave_base].len = 0; s_enclave_mem_region[enclave_base].prot = 0; + - se_mutex_unlock(&s_enclave_mutex); if (enclave_error != NULL) *enclave_error = ENCLAVE_ERROR_SUCCESS; return enclave_base; } +static bool enclave_do_mprotect_region(void* target_address, size_t target_size, int prot, uint32_t* enclave_error) +{ + int hfile = -1; + // find the enclave base + void* enclave_base = get_enclave_base_address_from_address(target_address); + if (enclave_base == NULL) { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_ENCLAVE; + return false; + } + + if (s_driver_type == SGX_DRIVER_IN_KERNEL) + { + hfile = get_file_handle_from_address(target_address); + } + + LockGuard lock(&s_enclave_mutex); + auto enclave_mem_region = &s_enclave_mem_region[enclave_base]; + //if target_size =0, means mprotect the last region + if(target_size !=0) + { + + void* next_page = (void*)((uint64_t)enclave_mem_region->addr + (uint64_t)enclave_mem_region->len); + if ((enclave_mem_region->prot != prot) || (target_address != next_page)) { + if (enclave_mem_region->len != 0) { + //the new load of enclave data either has a different protection or is not contiguous with the last one, mprotect/mmap the range stored in memory region structure + int ret = 0; + if (hfile != -1) { + if (MAP_FAILED == mmap(enclave_mem_region->addr, enclave_mem_region->len, + enclave_mem_region->prot, MAP_SHARED | MAP_FIXED, hfile, 0)) + ret=-1; + } + else + ret = mprotect(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot); + if (0 != ret) { + if (enclave_error != NULL) + *enclave_error = error_driver2api(-1, errno); + return false; + } + } + //record the current load of enclave data in the memory region structure + enclave_mem_region->addr = target_address; + enclave_mem_region->len = target_size; + enclave_mem_region->prot = prot; + } else { + //this load of enclave data is extending the memory region + enclave_mem_region->len += target_size; + } + } + else + { + if (enclave_mem_region->addr != 0) { + //the new load of enclave data either has a different protection or is not contiguous with the last one, mprotect/mmap the range stored in memory region structure + int ret = 0; + if (hfile != -1) { + if (MAP_FAILED == mmap(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot, MAP_SHARED | MAP_FIXED, hfile, 0)) + ret=-1; + } + else + ret= mprotect(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot); + if (0 != ret) { + if (enclave_error != NULL) + *enclave_error = error_driver2api(-1, errno); + return false; + } + //record the current load of enclave data in the memory region structure + enclave_mem_region->addr = 0; //just in case we need to call enclave_initialize twice + } + } + + return true; +} + + /* enclave_load_data() * Parameters: * target_address [in] - The address in the enclave where you want to load the data. @@ -601,7 +671,10 @@ extern "C" size_t COMM_API enclave_load_data( sec_info_t sec_info; memset(&sec_info, 0, sizeof(sec_info_t)); - uint64_t image_offset = 0; + uint64_t elrange_start_address = 0; + enclave_elrange_t enclave_elrange; + + memset(&enclave_elrange, 0, sizeof(enclave_elrange)); sec_info.flags = data_properties; if (!(sec_info.flags & ENCLAVE_PAGE_THREAD_CONTROL)) @@ -637,9 +710,14 @@ extern "C" size_t COMM_API enclave_load_data( *enclave_error = ENCLAVE_INVALID_ADDRESS; return 0; } - if(s_enclave_elrange_map.count(enclave_base_addr) != 0 && s_enclave_elrange_map[enclave_base_addr]->elrange_size!= 0) + + if(get_elrange_from_base_address(enclave_base_addr, &enclave_elrange) == true) { - image_offset = s_enclave_elrange_map[enclave_base_addr]->enclave_start_address; + elrange_start_address = enclave_elrange.elrange_start_address; + } + else + { + elrange_start_address = reinterpret_cast(enclave_base_addr); } uint8_t* source = (uint8_t*)source_buffer; @@ -667,7 +745,7 @@ extern "C" size_t COMM_API enclave_load_data( addp.src = POINTER_TO_U64(source); } - addp.offset = POINTER_TO_U64((uint64_t)target_address - (uint64_t)enclave_base_addr + image_offset); + addp.offset = POINTER_TO_U64((uint64_t)target_address - elrange_start_address); addp.length = target_size; addp.secinfo = POINTER_TO_U64(&sec_info); if (!(data_properties & ENCLAVE_PAGE_UNVALIDATED)) @@ -743,35 +821,9 @@ extern "C" size_t COMM_API enclave_load_data( return 0; } - se_mutex_lock(&s_enclave_mutex); - auto enclave_mem_region = &s_enclave_mem_region[enclave_base]; - se_mutex_unlock(&s_enclave_mutex); - - void* next_page = (void*)((uint64_t)enclave_mem_region->addr + (uint64_t)enclave_mem_region->len); - if ((enclave_mem_region->prot != prot) || (target_address != next_page)) { - if (enclave_mem_region->len != 0) { - //the new load of enclave data either has a different protection or is not contiguous with the last one, mprotect/mmap the range stored in memory region structure - int ret = 0; - if (hfile != -1) { - if (MAP_FAILED == mmap(enclave_mem_region->addr, enclave_mem_region->len, - enclave_mem_region->prot, MAP_SHARED | MAP_FIXED, hfile, 0)) - ret=-1; - } - else - ret = mprotect(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot); - if (0 != ret) { - if (enclave_error != NULL) - *enclave_error = error_driver2api(-1, errno); - return 0; - } - } - //record the current load of enclave data in the memory region structure - enclave_mem_region->addr = target_address; - enclave_mem_region->len = target_size; - enclave_mem_region->prot = prot; - } else { - //this load of enclave data is extending the memory region - enclave_mem_region->len += target_size; + if(enclave_do_mprotect_region(target_address, target_size, prot, enclave_error) == false) + { + return 0; } if (enclave_error != NULL) @@ -779,6 +831,8 @@ extern "C" size_t COMM_API enclave_load_data( return target_size; } + + /* enclave_initialize() * Parameters: * base_address [in] - The enclave base address as returned from the enclave_create API. @@ -822,40 +876,22 @@ extern "C" bool COMM_API enclave_initialize( } //mprotect the last region - se_mutex_lock(&s_enclave_mutex); - auto enclave_mem_region = &s_enclave_mem_region[base_address]; - se_mutex_unlock(&s_enclave_mutex); - if (enclave_mem_region->addr != 0) { - //the new load of enclave data either has a different protection or is not contiguous with the last one, mprotect/mmap the range stored in memory region structure - int ret = 0; - if (hfile != -1) { - if (MAP_FAILED == mmap(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot, MAP_SHARED | MAP_FIXED, hfile, 0)) - ret=-1; - } - else - ret= mprotect(enclave_mem_region->addr, enclave_mem_region->len, enclave_mem_region->prot); - if (0 != ret) { - if (enclave_error != NULL) - *enclave_error = error_driver2api(-1, errno); - return 0; - } - //record the current load of enclave data in the memory region structure - enclave_mem_region->addr = 0; //just in case we need to call enclave_initialize twice + if(enclave_do_mprotect_region(base_address, 0, 0, enclave_error) == false) + { + return false; } int ret = 0; if ( s_driver_type == SGX_DRIVER_OUT_OF_TREE ) { //out-of-tree driver requires a launch token to be provided - se_mutex_lock(&s_enclave_mutex); + LockGuard lock(&s_enclave_mutex); std::map::iterator it = s_secs_attr.find(base_address); if (it == s_secs_attr.end()) { - se_mutex_unlock(&s_enclave_mutex); if (enclave_error != NULL) *enclave_error = ENCLAVE_INVALID_PARAMETER; return false; } - se_mutex_unlock(&s_enclave_mutex); sgx_launch_token_t launch_token; memset(launch_token, 0, sizeof(sgx_launch_token_t)); @@ -910,17 +946,16 @@ extern "C" bool COMM_API enclave_initialize( return false; } - se_mutex_lock(&s_enclave_mutex); + LockGuard lock(&s_enclave_mutex); std::map::iterator it = s_enclave_init.find(base_address); if (it != s_enclave_init.end() && it->second) { - se_mutex_unlock(&s_enclave_mutex); if (enclave_error != NULL) *enclave_error = ENCLAVE_ALREADY_INITIALIZED; return false; } s_enclave_init[base_address] = true; - se_mutex_unlock(&s_enclave_mutex); + if (enclave_error != NULL) *enclave_error = ENCLAVE_ERROR_SUCCESS; @@ -945,10 +980,9 @@ extern "C" bool COMM_API enclave_delete( return false; } - se_mutex_lock(&s_enclave_mutex); + LockGuard lock(&s_enclave_mutex); std::map::iterator it = s_enclave_size.find(base_address); if (it == s_enclave_size.end()) { - se_mutex_unlock(&s_enclave_mutex); if (enclave_error != NULL) *enclave_error = ENCLAVE_INVALID_PARAMETER; return false; @@ -963,7 +997,7 @@ extern "C" bool COMM_API enclave_delete( close_file(&hfile_temp); s_hfile.erase(base_address); } - se_mutex_unlock(&s_enclave_mutex); + if (0 != munmap(base_address, it->second)) { SE_TRACE(SE_TRACE_WARNING, "delete SGX enclave failed, error = %d\n", errno); @@ -1007,12 +1041,19 @@ bool COMM_API enclave_get_information( return false; } +static inline bool is_power_of_two(size_t n) +{ + return (n != 0) && (!(n & (n - 1))); +} + + static bool enclave_set_elrange( void* base_address, void* input_info, size_t input_info_size, uint32_t* enclave_error) { + if (s_driver_type == SGX_DRIVER_UNKNOWN) { if (false == get_driver_type(&s_driver_type)) @@ -1020,23 +1061,81 @@ static bool enclave_set_elrange( SE_TRACE(SE_TRACE_WARNING, "\nenclave_set_elrange: failed to find a driver\n"); if (enclave_error != NULL) *enclave_error = ENCLAVE_NOT_SUPPORTED; - return NULL; + return false; } if(s_driver_type == SGX_DRIVER_OUT_OF_TREE) { if (enclave_error != NULL) *enclave_error = ENCLAVE_NOT_SUPPORTED; - return NULL; + return false; } } + + //check the input parameters + enclave_elrange_t* input_data = reinterpret_cast(input_info); + if(input_data->elrange_size == 0) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + if(input_data->elrange_start_address > input_data->enclave_image_address) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + if((input_data->elrange_size % SE_PAGE_SIZE != 0) || + (input_data->elrange_start_address% SE_PAGE_SIZE != 0) || + (input_data->enclave_image_address% SE_PAGE_SIZE != 0)) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + if(!is_power_of_two(input_data->elrange_size)) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + if((input_data->elrange_start_address & (input_data->elrange_size -1 )) !=0) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + uint64_t elrange_end = input_data->elrange_start_address + input_data->elrange_size; + if(elrange_end < input_data->elrange_start_address || elrange_end < input_data->elrange_size) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + + if(input_data->enclave_image_address >= elrange_end) + { + if (enclave_error != NULL) + *enclave_error = ENCLAVE_INVALID_PARAMETER; + return false; + } + LockGuard lock(&s_enclave_info_mutex); if (s_enclave_elrange_map.count(base_address) != 0) { enclave_elrange_t *enclave_elrange = s_enclave_elrange_map[base_address]; - if (enclave_error) + if (enclave_elrange == NULL) + { + if (enclave_error) *enclave_error = ENCLAVE_UNEXPECTED; - return false; + return false; + } if (memcpy_s(enclave_elrange, sizeof(enclave_elrange_t), input_info, input_info_size)) { @@ -1081,7 +1180,7 @@ bool COMM_API enclave_set_information( COMM_IN size_t input_info_size, COMM_OUT_OPT uint32_t* enclave_error) { - if (base_address == NULL || input_info == NULL) + if (input_info == NULL) { if (enclave_error) *enclave_error = ENCLAVE_INVALID_PARAMETER; @@ -1096,7 +1195,7 @@ bool COMM_API enclave_set_information( } else { - if (input_info_size != sizeof(enclave_elrange_t)) + if (base_address == NULL || input_info_size != sizeof(enclave_elrange_t)) { if (enclave_error) *enclave_error = ENCLAVE_INVALID_PARAMETER; diff --git a/psw/enclave_common/sgx_enclave_common.h b/psw/enclave_common/sgx_enclave_common.h index a6e0ebe8..8cc8285d 100644 --- a/psw/enclave_common/sgx_enclave_common.h +++ b/psw/enclave_common/sgx_enclave_common.h @@ -93,7 +93,8 @@ typedef enum { } enclave_info_type_t; typedef struct enclave_elrange{ - uint64_t enclave_start_address; + uint64_t enclave_image_address; + uint64_t elrange_start_address; uint64_t elrange_size; }enclave_elrange_t; diff --git a/psw/urts/enclave.cpp b/psw/urts/enclave.cpp index efdc3242..4e298b5b 100644 --- a/psw/urts/enclave.cpp +++ b/psw/urts/enclave.cpp @@ -147,8 +147,7 @@ sgx_status_t CEnclave::initialize(const se_file_t& file, CLoader &ldr, const ui } m_enclave_info.struct_version = DEBUG_INFO_STRUCT_VERSION; - - + m_enclave_id = ldr.get_enclave_id(); m_start_addr = (void*)ldr.get_start_addr(); m_size = enclave_size; @@ -576,6 +575,8 @@ int CEnclave::set_extra_debug_info(secs_t& secs, CLoader &ldr) void *g_peak_rsrv_mem_committed_addr = ldr.get_symbol_address("g_peak_rsrv_mem_committed"); m_enclave_info.g_peak_heap_used_addr = g_peak_heap_used_addr; m_enclave_info.g_peak_rsrv_mem_committed_addr = g_peak_rsrv_mem_committed_addr; + m_enclave_info.elrange_start_address = ldr.get_elrange_start_addr(); + m_enclave_info.elrange_size = ldr.get_elrange_size(); m_enclave_info.start_addr = secs.base; m_enclave_info.misc_select = secs.misc_select; diff --git a/psw/urts/linux/debugger_support.cpp b/psw/urts/linux/debugger_support.cpp index e8a84759..f8796189 100644 --- a/psw/urts/linux/debugger_support.cpp +++ b/psw/urts/linux/debugger_support.cpp @@ -121,7 +121,16 @@ extern "C" void push_ocall_frame(uintptr_t frame_point, tcs_t* tcs, CTrustThread CEnclave* enclave = trust_thread->get_enclave(); assert(enclave != NULL); enclave->push_ocall_frame(container_of(frame_point, ocall_frame_t, xbp), trust_thread); - notify_gdb_to_update(enclave->get_start_address(), tcs, (uintptr_t)container_of(frame_point, ocall_frame_t, xbp)); + + if(enclave->get_debug_info()->elrange_size == 0 || ((enclave->get_debug_info()->enclave_type & ET_SIM) ==ET_SIM)) + { + notify_gdb_to_update(enclave->get_start_address(), tcs, (uintptr_t)container_of(frame_point, ocall_frame_t, xbp)); + } + else + { + notify_gdb_to_update(reinterpret_cast(enclave->get_debug_info()->elrange_start_address), + tcs, (uintptr_t)container_of(frame_point, ocall_frame_t, xbp)); + } } extern "C" void pop_ocall_frame(tcs_t* tcs, CTrustThread *trust_thread) diff --git a/psw/urts/loader.cpp b/psw/urts/loader.cpp index 1e0b1939..ca44e5b3 100644 --- a/psw/urts/loader.cpp +++ b/psw/urts/loader.cpp @@ -92,6 +92,8 @@ CLoader::CLoader(uint8_t *mapped_file_base, BinParser &parser) : m_mapped_file_base(mapped_file_base) , m_enclave_id(0) , m_start_addr(NULL) + , m_elrange_start_address(0) + , m_elrange_size(0) , m_metadata(NULL) , m_parser(parser) { @@ -113,6 +115,16 @@ const void* CLoader::get_start_addr() const return m_start_addr; } +uint64_t CLoader::get_elrange_start_addr() const +{ + return m_elrange_start_address; +} + +uint64_t CLoader::get_elrange_size() const +{ + return m_elrange_size; +} + const std::vector>& CLoader::get_tcs_list() const { return m_tcs_list; @@ -494,7 +506,7 @@ int CLoader::build_secs(sgx_attributes_t * const secs_attr, sgx_config_id_t *con { memset(&m_secs, 0, sizeof(secs_t)); //should set resvered field of secs as 0. //create secs structure. - m_secs.base = 0; //base is allocated by driver. set it as 0 + m_secs.base = 0; m_secs.size = m_metadata->enclave_size; m_secs.misc_select = misc_attr->misc_select; @@ -529,15 +541,19 @@ int CLoader::build_secs(sgx_attributes_t * const secs_attr, sgx_config_id_t *con { enclave_elrange_t elrange; memset(&elrange, 0 , sizeof(enclave_elrange_t)); - elrange.enclave_start_address = medata->enclave_start_address; + elrange.enclave_image_address = medata->enclave_image_address; + elrange.elrange_start_address = medata->elrange_start_address; elrange.elrange_size = medata->elrange_size; - int ret = enclave_creator->set_enclave_info(reinterpret_cast(medata->enclave_start_address), ENCLAVE_ELRANGE, &elrange, sizeof(enclave_elrange_t)); + int ret = enclave_creator->set_enclave_info(reinterpret_cast(medata->enclave_image_address), ENCLAVE_ELRANGE, + reinterpret_cast(&elrange), sizeof(enclave_elrange_t)); if(SGX_SUCCESS != ret) { return ret; - } + } + m_elrange_start_address = medata->elrange_start_address; + m_elrange_size = medata->elrange_size; } - m_start_addr = reinterpret_cast(medata->enclave_start_address); + m_start_addr = reinterpret_cast(medata->enclave_image_address); } int ret = enclave_creator->create_enclave(&m_secs, &m_enclave_id, &m_start_addr, is_ae(&m_metadata->enclave_css)); diff --git a/psw/urts/loader.h b/psw/urts/loader.h index a5eee928..04008e5e 100644 --- a/psw/urts/loader.h +++ b/psw/urts/loader.h @@ -62,6 +62,8 @@ public: int destroy_enclave(); sgx_enclave_id_t get_enclave_id() const; const void* get_start_addr() const; + uint64_t get_elrange_start_addr() const; + uint64_t get_elrange_size() const; const secs_t& get_secs() const; const std::vector>& get_tcs_list() const; void* get_symbol_address(const char* const sym); @@ -92,6 +94,8 @@ private: uint8_t *m_mapped_file_base; sgx_enclave_id_t m_enclave_id; void *m_start_addr; + uint64_t m_elrange_start_address; + uint64_t m_elrange_size; // the TCS list std::vector> m_tcs_list; diff --git a/psw/urts/parser/update_global_data.hxx b/psw/urts/parser/update_global_data.hxx index 4e187d49..cb29f955 100644 --- a/psw/urts/parser/update_global_data.hxx +++ b/psw/urts/parser/update_global_data.hxx @@ -143,7 +143,8 @@ namespace { entry_cnt++; } - global_data->enclave_start_address = metadata->enclave_start_address; + global_data->enclave_image_address = metadata->enclave_image_address; + global_data->elrange_start_address= metadata->elrange_start_address; global_data->elrange_size = metadata->elrange_size; return true; } diff --git a/sdk/debugger_interface/linux/gdb-sgx-plugin/gdb_sgx_plugin.py b/sdk/debugger_interface/linux/gdb-sgx-plugin/gdb_sgx_plugin.py index 878e0709..feab4542 100755 --- a/sdk/debugger_interface/linux/gdb-sgx-plugin/gdb_sgx_plugin.py +++ b/sdk/debugger_interface/linux/gdb-sgx-plugin/gdb_sgx_plugin.py @@ -52,8 +52,9 @@ KB_SIZE = 1024 # pointer: next_enclave_info, start_addr, tcs_list, lpFileName, # g_peak_heap_used_addr, g_peak_rsrv_mem_committed_addr # int32_t: enclave_type, file_name_size -ENCLAVE_INFO_SIZE = 6 * 8 + 2 * 4 -INFO_FMT = 'QQQIIQQQ' +# uint64_t: elrange_start_address, elrange_size +ENCLAVE_INFO_SIZE = 8 * 8 + 2 * 4 +INFO_FMT = 'QQQIIQQQQQ' ENCLAVES_ADDR = {} # The following definitions should strictly align with the struct of @@ -122,7 +123,8 @@ class enclave_info(object): such as start address, stack addresses, stack size, etc. The enclave information is for one enclave.""" def __init__(self, _next_ei, _start_addr, _enclave_type, _stack_addr_list, \ - _stack_size, _enclave_path, _heap_addr, _tcs_addr_list, _rsrv_mem_addr): + _stack_size, _enclave_path, _heap_addr, _tcs_addr_list, _rsrv_mem_addr, \ + _elrange_start_address, _elrange_size): self.next_ei = _next_ei self.start_addr = _start_addr self.enclave_type = _enclave_type @@ -132,6 +134,8 @@ class enclave_info(object): self.heap_addr = _heap_addr self.tcs_addr_list = _tcs_addr_list self.rsrv_mem_addr = _rsrv_mem_addr + self.elrange_start_address = _elrange_start_address + self.elrange_size = _elrange_size def __str__(self): print ("stack address list = {0:s}".format(self.stack_addr_list)) return "start_addr = %#x, enclave_path = \"%s\", stack_size = %d" \ @@ -241,13 +245,17 @@ class enclave_info(object): return -1 tcs_tuple = struct.unpack_from(TCS_INFO_FMT, tcs_str) offset = tcs_tuple[7] - if offset > self.start_addr: - offset = offset - self.start_addr if SIZE == 4: td_fmt = '20I' elif SIZE == 8: td_fmt = '20Q' - td_str = read_from_memory(self.start_addr+offset, (20*SIZE)) + + if (self.elrange_size == 0) or ((self.enclave_type & ET_SIM) == ET_SIM): + td_addr = self.start_addr + offset + else: + td_addr = self.elrange_start_address + offset + + td_str = read_from_memory(td_addr, (20*SIZE)) if td_str == None: return -1 td_tuple = struct.unpack_from(td_fmt, td_str) @@ -403,18 +411,17 @@ def retrieve_enclave_info(info_addr = 0): return None tcs_t_tuple = struct.unpack_from(TCS_INFO_FMT, tcs_t_str) - offset = tcs_t_tuple[7] - - if offset > info_tuple[1]: - offset = offset - info_tuple[1] - if SIZE == 4: td_fmt = '4I' elif SIZE == 8: td_fmt = '4Q' #get thread_data_t address - td_addr = offset + info_tuple[1] #thread_data_t = tcs.of_base + debug_enclave_info.start_addr + if (info_tuple[9] == 0) or ((info_tuple[3] & ET_SIM) == ET_SIM): + td_addr = tcs_t_tuple[7] + info_tuple[1] #thread_data_t = tcs.of_base + debug_enclave_info.start_addr + else: + td_addr = tcs_t_tuple[7] + info_tuple[8] #thread_data_t = tcs.of_base + debug_enclave_info.elrange_start_address + td_str = read_from_memory(td_addr, (4*SIZE)) if td_str == None: return None @@ -493,7 +500,7 @@ def retrieve_enclave_info(info_addr = 0): last_ocall_frame = last_frame node = enclave_info(info_tuple[0], info_tuple[1], info_tuple[3], stack_addr_list, \ - stacksize, enclave_path, info_tuple[6], tcs_addr_list, info_tuple[7]) + stacksize, enclave_path, info_tuple[6], tcs_addr_list, info_tuple[7], info_tuple[8], info_tuple[9]) return node def handle_load_event(): @@ -586,14 +593,11 @@ class UpdateOcallFrame(gdb.Breakpoint): tcs_tuple = struct.unpack_from(TCS_INFO_FMT, tcs_str) offset = tcs_tuple[7] - if offset > base_addr: - offset = offset - base_addr - if SIZE == 4: td_fmt = '4I' elif SIZE == 8: td_fmt = '4Q' - + td_str = read_from_memory(base_addr+offset, (4*SIZE)) if td_str == None: return False diff --git a/sdk/sign_tool/SignTool/enclave_creator_sign.cpp b/sdk/sign_tool/SignTool/enclave_creator_sign.cpp index d50dc387..1bd42815 100644 --- a/sdk/sign_tool/SignTool/enclave_creator_sign.cpp +++ b/sdk/sign_tool/SignTool/enclave_creator_sign.cpp @@ -54,7 +54,9 @@ #define DATA_BLOCK_SIZE 64 #define EID 0x44444444 -uint64_t enclave_start_address = 0; + +uint64_t enclave_image_address = 0; +uint64_t elrange_start_address = 0; uint64_t elrange_size = 0; @@ -153,7 +155,7 @@ int EnclaveCreatorST::add_enclave_page(sgx_enclave_id_t enclave_id, void *src, u uint64_t page_offset = (uint64_t)offset; if(elrange_size != 0) { - page_offset += enclave_start_address; + page_offset += enclave_image_address - elrange_start_address; } uint8_t eadd_val[SIZE_NAMED_VALUE] = "EADD\0\0\0"; @@ -338,7 +340,8 @@ int EnclaveCreatorST::remove_range(uint64_t fromaddr, uint64_t numpages) int EnclaveCreatorST::set_enclave_info(void* base_address, uint32_t info_type, void* input_info, size_t input_info_size) { - if (base_address == NULL || input_info == NULL) + UNUSED(base_address); + if (input_info == NULL) { return SGX_ERROR_INVALID_PARAMETER; } @@ -354,7 +357,8 @@ int EnclaveCreatorST::set_enclave_info(void* base_address, uint32_t info_type, v return SGX_ERROR_INVALID_PARAMETER; } enclave_elrange_t *enclave_range = (enclave_elrange_t*) input_info; - enclave_start_address = enclave_range->enclave_start_address; + enclave_image_address = enclave_range->enclave_image_address; + elrange_start_address = enclave_range->elrange_start_address; elrange_size = enclave_range->elrange_size; } diff --git a/sdk/sign_tool/SignTool/manage_metadata.cpp b/sdk/sign_tool/SignTool/manage_metadata.cpp index aa0c9bb8..2871991e 100644 --- a/sdk/sign_tool/SignTool/manage_metadata.cpp +++ b/sdk/sign_tool/SignTool/manage_metadata.cpp @@ -343,7 +343,8 @@ bool CMetadata::modify_metadata(const xml_parameter_t *parameter) m_metadata->magic_num = METADATA_MAGIC; m_metadata->desired_misc_select = 0; m_metadata->tcs_min_pool = (uint32_t)parameter[TCSMINPOOL].value; - m_metadata->enclave_start_address = parameter[ENCLAVESTARTADDRESS].value; + m_metadata->enclave_image_address = parameter[ENCLAVEIMAGEADDRESS].value; + m_metadata->elrange_start_address = parameter[ELRANGESTARTADDRESS].value; m_metadata->elrange_size = parameter[ELRANGESIZE].value; m_metadata->enclave_css.body.misc_select = (uint32_t)parameter[MISCSELECT].value; m_metadata->enclave_css.body.misc_mask = (uint32_t)parameter[MISCMASK].value; @@ -485,12 +486,17 @@ bool CMetadata::check_xml_parameter(const xml_parameter_t *parameter) return false; } - if(parameter[ENCLAVESTARTADDRESS].flag == 0 && parameter[ELRANGESIZE].flag !=0) + if(parameter[ENCLAVEIMAGEADDRESS].flag != 0 && parameter[ELRANGESIZE].flag ==0) { - se_trace(SE_TRACE_ERROR, SET_ELRANGE_ERROR); + se_trace(SE_TRACE_ERROR, SET_ENCLAVEIMAGEADDRESS_SET_ERROR); return false; } + if(parameter[ELRANGESTARTADDRESS].flag != 0 && parameter[ELRANGESIZE].flag ==0) + { + se_trace(SE_TRACE_ERROR, SET_ELRANGESTARTADDRESS_SET_ERROR); + return false; + } m_create_param.heap_init_size = parameter[HEAPINITSIZE].flag ? parameter[HEAPINITSIZE].value : parameter[HEAPMAXSIZE].value; m_create_param.heap_min_size = parameter[HEAPMINSIZE].value; @@ -590,27 +596,58 @@ bool CMetadata::build_layout_entries() return false; } - if(m_metadata->enclave_start_address) - { - if(m_metadata->enclave_start_address%SE_PAGE_SIZE != 0) - { - se_trace(SE_TRACE_ERROR, SET_ENCLAVESTARTADDRESS_ALIGN_ERROR); - return false; - } - } - if(m_metadata->elrange_size) { + if(m_metadata->enclave_image_address % SE_PAGE_SIZE != 0) + { + se_trace(SE_TRACE_ERROR, SET_ENCLAVEIMAGEADDRESS_ALIGN_ERROR); + return false; + } + + if(m_metadata->elrange_start_address % SE_PAGE_SIZE != 0) + { + se_trace(SE_TRACE_ERROR, SET_ELRANGESTARTADDRESS_PAGE_ALIGN_ERROR); + return false; + } + if(m_metadata->elrange_size%SE_PAGE_SIZE != 0) { se_trace(SE_TRACE_ERROR, SET_ELRANGE_PAGE_ALIGN_ERROR); return false; } - if(m_metadata->enclave_start_address + m_rva > m_metadata->elrange_size) + + if((m_metadata->elrange_start_address & (m_metadata->elrange_size -1)) != 0) { - se_trace(SE_TRACE_ERROR, SET_ENCLAVESTARTADDRESS_RANGE_ERROR); + se_trace(SE_TRACE_ERROR, SET_ELRANGESTARTADDRESS_ALIGN_ERROR); return false; } + + if(m_metadata->elrange_start_address > m_metadata->enclave_image_address) + { + se_trace(SE_TRACE_ERROR, SET_ELRANGESTARTADDRESS_RANGE_ERROR); + return false; + } + + uint64_t enclave_end = m_metadata->enclave_image_address + m_rva; + if(enclave_end < m_metadata->enclave_image_address || enclave_end < m_rva) + { + se_trace(SE_TRACE_ERROR, SET_ENCLAVEIMAGEADDRESS_ERROR); + return false; + } + + uint64_t elrange_end = m_metadata->elrange_start_address+ m_metadata->elrange_size; + if(elrange_end < m_metadata->elrange_start_address || elrange_end < m_metadata->elrange_size) + { + se_trace(SE_TRACE_ERROR, SET_ELRANGE_ERROR); + return false; + } + + if(enclave_end > elrange_end) + { + se_trace(SE_TRACE_ERROR, SET_ELRANGE_RANGE_ERROR); + return false; + } + if(!is_power_of_two(m_metadata->elrange_size)) { se_trace(SE_TRACE_ERROR, SET_ELRANGE_ALIGN_ERROR); @@ -1123,7 +1160,7 @@ bool CMetadata::build_tcs_template(tcs_t *tcs) uint64_t offset = 0; if(m_metadata->elrange_size != 0) { - offset = m_metadata->enclave_start_address; + offset = m_metadata->enclave_image_address - m_metadata->elrange_start_address; } tcs->oentry = m_parser->get_symbol_rva("enclave_entry"); if(tcs->oentry == 0) diff --git a/sdk/sign_tool/SignTool/manage_metadata.h b/sdk/sign_tool/SignTool/manage_metadata.h index 7c4625dd..ab126afa 100644 --- a/sdk/sign_tool/SignTool/manage_metadata.h +++ b/sdk/sign_tool/SignTool/manage_metadata.h @@ -76,7 +76,8 @@ typedef enum _para_type_t ISVFAMILYID_L, ISVEXTPRODID_H, ISVEXTPRODID_L, - ENCLAVESTARTADDRESS, + ENCLAVEIMAGEADDRESS, + ELRANGESTARTADDRESS, ELRANGESIZE } para_type_t; diff --git a/sdk/sign_tool/SignTool/sign_tool.cpp b/sdk/sign_tool/SignTool/sign_tool.cpp index 8b8c1061..1d9d5ef0 100644 --- a/sdk/sign_tool/SignTool/sign_tool.cpp +++ b/sdk/sign_tool/SignTool/sign_tool.cpp @@ -1292,8 +1292,9 @@ int main(int argc, char* argv[]) {"ISVFAMILYID_L", ISVFAMILYID_MAX , 0, 0, 0}, {"ISVEXTPRODID_H", ISVEXTPRODID_MAX, 0, 0, 0}, {"ISVEXTPRODID_L", ISVEXTPRODID_MAX, 0, 0, 0}, - {"EnclaveStartAddress", 0xFFFFFFFFFFFFFFFF, 0x1000, 0, 0}, - {"ELRangeSize", 0xFFFFFFFFFFFFFFFF, 0x1000, 0, 0}}; + {"EnclaveImageAddress", 0xFFFFFFFFFFFFFFFF, 0, 0, 0}, + {"ELRangeStartAddress", 0xFFFFFFFFFFFFFFFF, 0, 0, 0}, + {"ELRangeSize", 0xFFFFFFFFFFFFFFFF, 0x2000, 0, 0}}; const char *path[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; uint8_t enclave_hash[SGX_HASH_SIZE] = {0}; diff --git a/sdk/sign_tool/SignTool/util_st.h b/sdk/sign_tool/SignTool/util_st.h index 32aa60c0..da61d35c 100644 --- a/sdk/sign_tool/SignTool/util_st.h +++ b/sdk/sign_tool/SignTool/util_st.h @@ -145,11 +145,17 @@ #define SET_TCS_MIN_POOL_ERROR "Minimum number of TCS Pool is not correct.\n" #define SET_ENABLE_KSS_ERROR "KSS must be enabled if ISVEXTPRODID or ISVFAMILYID is set.\n" -#define SET_ELRANGE_ERROR "EnclaveStartAddress must be set when ELRangeSize is set.\n" -#define SET_ENCLAVESTARTADDRESS_ALIGN_ERROR "EnclaveStartAddress setting is not correct: ImageOffset should be enclave size aligned.\n" -#define SET_ENCLAVESTARTADDRESS_RANGE_ERROR "EnclaveStartAddress and ELRangeSize setting are not correct: ELRangeSize should large enough to fit the enclave image loaded at EnclaveStartAddress.\n" -#define SET_ELRANGE_ALIGN_ERROR "ELRangeSize setting is not correct: ELRangeSize should be power of 2.\n" -#define SET_ELRANGE_PAGE_ALIGN_ERROR "ELRangeSize setting is not correct: ELRangeSize is not page aligned.\n" +#define SET_ENCLAVEIMAGEADDRESS_SET_ERROR "ELRangeSize must be set when EnclaveImageAddress is set.\n" +#define SET_ENCLAVEIMAGEADDRESS_ERROR "EnclaveImageAddress setting is not correct. EnclaveImageAddress plus EnclaveSize should not overflow.\n" +#define SET_ENCLAVEIMAGEADDRESS_ALIGN_ERROR "EnclaveImageAddress setting is not correct: EnclaveImageAddress is not page aligned.\n" +#define SET_ELRANGESTARTADDRESS_SET_ERROR "ELRangeSize must be set when ELRangeStartAddress is set.\n\n" +#define SET_ELRANGESTARTADDRESS_PAGE_ALIGN_ERROR "ELRangeStartAddress setting is not correct: ELRangeStartAddress is not page aligned.\n" +#define SET_ELRANGESTARTADDRESS_ALIGN_ERROR "ELRangeStartAddress and ELRangeSize setting are not correct: ELRangeStartAddress should be aligned on an ELRangeSize boundary.\n" +#define SET_ELRANGESTARTADDRESS_RANGE_ERROR "ELRangeStartAddress setting is not correct: ELRangeStartAddress should not bigger than EnclaveImageAddress.\n" +#define SET_ELRANGE_ERROR "ELRange setting is not correct. ELRangeStartAddress plus ELRangeSize should not overflow.\n" +#define SET_ELRANGE_RANGE_ERROR "ELRange setting is not correct: ELRange should be large enough to fit the enclave image loaded at EnclaveImageAddress.\n" +#define SET_ELRANGE_ALIGN_ERROR "ELRangeSize setting is not correct: ELRangeSize should be power of 2.\n" +#define SET_ELRANGE_PAGE_ALIGN_ERROR "ELRangeSize setting is not correct: ELRangeSize is not page aligned.\n" diff --git a/sdk/simulation/driver_api/driver_api.cpp b/sdk/simulation/driver_api/driver_api.cpp index a78e8384..7e05ba26 100644 --- a/sdk/simulation/driver_api/driver_api.cpp +++ b/sdk/simulation/driver_api/driver_api.cpp @@ -73,7 +73,7 @@ int create_enclave(secs_t *secs, SE_TRACE(SE_TRACE_DEBUG, "out of memory.\n"); return SGX_ERROR_OUT_OF_MEMORY; } - + *start_addr = ce->get_secs()->base; *enclave_id = ce->get_enclave_id(); secs->base = *start_addr; diff --git a/sdk/simulation/uinst/enclave_mngr.cpp b/sdk/simulation/uinst/enclave_mngr.cpp index f606ea3e..3ae13a9b 100644 --- a/sdk/simulation/uinst/enclave_mngr.cpp +++ b/sdk/simulation/uinst/enclave_mngr.cpp @@ -75,6 +75,7 @@ CEnclaveSim::CEnclaveSim(const secs_t* secs) memcpy_s(&m_secs, sizeof(m_secs), secs, sizeof(*secs)); m_enclave_id = gen_enclave_id(); + m_image_offset = 0; } CEnclaveSim::~CEnclaveSim() diff --git a/sdk/simulation/uinst/td_mngr.h b/sdk/simulation/uinst/td_mngr.h index c7c330a4..063a6ca9 100644 --- a/sdk/simulation/uinst/td_mngr.h +++ b/sdk/simulation/uinst/td_mngr.h @@ -43,6 +43,7 @@ typedef struct _tcs_sim_t size_t tcs_state; uintptr_t saved_dtv; uintptr_t saved_fs_gs_0; + uint64_t tcs_offset_update_flag; } tcs_sim_t; #define TCS_STATE_INACTIVE 0 //The TCS is available for a normal EENTER diff --git a/sdk/simulation/uinst/u_instructions.cpp b/sdk/simulation/uinst/u_instructions.cpp index 45fe53c3..7fbee6df 100644 --- a/sdk/simulation/uinst/u_instructions.cpp +++ b/sdk/simulation/uinst/u_instructions.cpp @@ -36,6 +36,7 @@ #include #include +#include #include "arch.h" #include "util.h" @@ -57,6 +58,9 @@ static uintptr_t _ECREATE (page_info_t* pi); static uintptr_t _EADD (page_info_t* pi, void* epc_lin_addr); static uintptr_t _EREMOVE(const void* epc_lin_addr); +extern "C" bool get_elrange_start_address(void* base_address, uint64_t &elrange_start_address); + + //////////////////////////////////////////////////////////////////////// #define __GP__() exit(EXIT_FAILURE) @@ -151,21 +155,34 @@ uintptr_t _ECREATE(page_info_t* pi) CEnclaveSim* ce = new CEnclaveSim(secs); void* addr; - if(secs->base != NULL) + uint64_t elrange_start_address = 0; + uint64_t image_offset = 0; + bool ret = get_elrange_start_address(secs->base, elrange_start_address); + int mmap_flag = MAP_PRIVATE | MAP_ANONYMOUS; + if(ret == true) { - ce->set_image_offset((uint64_t)secs->base); + image_offset = reinterpret_cast(secs->base) - elrange_start_address; + mmap_flag |= MAP_FIXED; } - + // `ce' is not checked against NULL, since it is not // allocated with new(std::no_throw). - addr = se_virtual_alloc(secs->base, (size_t)secs->size, MEM_COMMIT); - if (addr == NULL) { + addr = mmap(secs->base, (size_t)secs->size, PROT_READ | PROT_WRITE, mmap_flag, -1, 0); + if(MAP_FAILED == addr) + { delete ce; return 0; } // Mark all the memory inaccessible. se_virtual_protect(addr, (size_t)secs->size, SGX_PROT_NONE); + + //set image_offset + if(image_offset != 0) + { + ce->set_image_offset(image_offset); + } + ce->get_secs()->base = addr; CEnclaveMngr::get_instance()->add(ce); @@ -255,12 +272,13 @@ void _SE3(uintptr_t xax, uintptr_t xbx, GP_ON_EENTER(tcs->cssa >= tcs->nssa); image_offset = ce->get_image_offset(); - if(image_offset!=0 && tcs->oentry > image_offset) + if(image_offset!=0 && tcs_sim->tcs_offset_update_flag == false) { tcs->oentry -= image_offset; tcs->ossa -= image_offset; tcs->ofs_base -= image_offset; tcs->ogs_base -= image_offset; + tcs_sim->tcs_offset_update_flag = true; } secs = ce->get_secs(); @@ -279,7 +297,7 @@ void _SE3(uintptr_t xax, uintptr_t xbx, xcx = p_pt_regs->xip; xip = reinterpret_cast(enclave_base_addr); - GP_ON_EENTER(xip == 0); + //GP_ON_EENTER(xip == 0); //set the _tls_array to point to the self_addr of TLS section inside the enclave GP_ON_EENTER(td_mngr_set_td(enclave_base_addr, tcs) == false); diff --git a/sdk/simulation/urtssim/enclave_creator_sim.cpp b/sdk/simulation/urtssim/enclave_creator_sim.cpp index 233c50af..ba781aa2 100644 --- a/sdk/simulation/urtssim/enclave_creator_sim.cpp +++ b/sdk/simulation/urtssim/enclave_creator_sim.cpp @@ -44,6 +44,8 @@ #include "rts_sim.h" #include #include +#include "sgx_enclave_common.h" +#include #include #include @@ -72,6 +74,34 @@ static void cleanup_openssl(void) } +static Mutex s_enclave_info_mutex; +static std::maps_enclave_elrange_map; + +__attribute__((destructor)) +static void enclave_elrange_cleanup(void) +{ + for (auto &res:s_enclave_elrange_map) + { + auto elrange = res.second; + delete elrange; + elrange = NULL; + } +} + +extern "C" bool get_elrange_start_address(void* base_address, uint64_t &elrange_start_address) +{ + LockGuard lock(&s_enclave_info_mutex); + bool ret = false; + if(s_enclave_elrange_map.count(base_address) != 0) + { + elrange_start_address = s_enclave_elrange_map[base_address]->elrange_start_address; + ret = true; + } + return ret; +} + + + EnclaveCreator* g_enclave_creator = new EnclaveCreatorSim(); int EnclaveCreatorSim::create_enclave(secs_t *secs, sgx_enclave_id_t *enclave_id, void **start_addr, bool ae) @@ -180,7 +210,6 @@ int EnclaveCreatorSim::destroy_enclave(sgx_enclave_id_t enclave_id, uint64_t enc if(enclave == NULL) return SGX_ERROR_INVALID_ENCLAVE_ID; - return ::destroy_enclave(enclave_id); } @@ -306,12 +335,86 @@ int EnclaveCreatorSim::remove_range(uint64_t fromaddr, uint64_t numpages) return SGX_SUCCESS; } + + int EnclaveCreatorSim::set_enclave_info(void* base_address, uint32_t info_type, void* input_info, size_t input_info_size) { - UNUSED(base_address); - UNUSED(info_type); - UNUSED(input_info); - UNUSED(input_info_size); + UNUSED(base_address); + if (input_info == NULL) + { + return SGX_ERROR_INVALID_PARAMETER; + } + + if (info_type != ENCLAVE_ELRANGE) + { + return SGX_ERROR_FEATURE_NOT_SUPPORTED; + } + else + { + if (input_info_size != sizeof(enclave_elrange_t)) + { + return SGX_ERROR_INVALID_PARAMETER; + } + //check the input parameters + enclave_elrange_t* input_data = reinterpret_cast(input_info); + if(input_data->elrange_size == 0) + { + return ENCLAVE_INVALID_PARAMETER; + } + + if(input_data->elrange_start_address > input_data->enclave_image_address) + { + return ENCLAVE_INVALID_PARAMETER; + } + + if((input_data->elrange_size % SE_PAGE_SIZE != 0) || + (input_data->elrange_start_address% SE_PAGE_SIZE != 0) || + (input_data->enclave_image_address% SE_PAGE_SIZE != 0)) + { + return ENCLAVE_INVALID_PARAMETER; + } + + if((input_data->elrange_start_address & (input_data->elrange_size -1 )) !=0) + { + return ENCLAVE_INVALID_PARAMETER; + } + + uint64_t elrange_end = input_data->elrange_start_address + input_data->elrange_size; + if(elrange_end < input_data->elrange_start_address || elrange_end < input_data->elrange_size) + { + return ENCLAVE_INVALID_PARAMETER; + } + + LockGuard lock(&s_enclave_info_mutex); + if (s_enclave_elrange_map.count(base_address) != 0) + { + enclave_elrange_t *enclave_elrange = s_enclave_elrange_map[base_address]; + if (enclave_elrange == NULL) + { + return SGX_ERROR_UNEXPECTED; + } + + if (memcpy_s(enclave_elrange, sizeof(enclave_elrange_t), input_info, input_info_size)) + { + return SGX_ERROR_UNEXPECTED; + } + } + else + { + enclave_elrange_t *enclave_elrange = new(std::nothrow) enclave_elrange_t; + if (enclave_elrange == NULL) + { + return SGX_ERROR_OUT_OF_MEMORY; + } + memset(enclave_elrange, 0, sizeof(enclave_elrange_t)); + if (memcpy_s(enclave_elrange, sizeof(enclave_elrange_t), input_info, input_info_size)) + { + return SGX_ERROR_UNEXPECTED; + } + s_enclave_elrange_map[base_address] = enclave_elrange; + } + } + return SGX_SUCCESS; } diff --git a/sdk/trts/init_enclave.cpp b/sdk/trts/init_enclave.cpp index fc009023..98b53276 100644 --- a/sdk/trts/init_enclave.cpp +++ b/sdk/trts/init_enclave.cpp @@ -61,7 +61,7 @@ uint64_t g_enclave_size __attribute__((section(RELRO_SECTION_NAME))) = 0; const volatile global_data_t g_global_data __attribute__((section(".niprod"))) = {VERSION_UINT, 1, 2, 3, 4, 5, 6, 0, 0, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, {{{0, 0, 0, 0, 0, 0, 0}}}, 0, 0}; + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, {{{0, 0, 0, 0, 0, 0, 0}}}, 0, 0, 0}; uint32_t g_enclave_state __attribute__((section(".nipd"))) = ENCLAVE_INIT_NOT_STARTED; uint32_t g_cpu_core_num __attribute__((section(RELRO_SECTION_NAME))) = 0; @@ -119,18 +119,15 @@ extern "C" int init_enclave(void *enclave_base, void *ms) g_enclave_base = (uint64_t)&__ImageBase; g_enclave_size = g_global_data.enclave_size; - if(g_global_data.enclave_start_address != 0) + if(g_global_data.elrange_size != 0) { - //__ImageBase should the same as enclave_start_address - if(g_global_data.enclave_start_address != g_enclave_base) + //__ImageBase should be the same as enclave_start_address + if(g_global_data.enclave_image_address != g_enclave_base) { abort(); } - } - if(g_global_data.elrange_size != 0) - { //if elrange_size is set, we should set enclave_base and enclave_size to correct value - g_enclave_base = 0; + g_enclave_base = g_global_data.elrange_start_address; g_enclave_size = g_global_data.elrange_size; } @@ -183,7 +180,10 @@ extern "C" int init_enclave(void *enclave_base, void *ms) #ifdef SE_SIM memset_s(GET_PTR(void, enclave_base, g_global_data.heap_offset), g_global_data.heap_size, 0, g_global_data.heap_size); - memset_s(GET_PTR(void, enclave_base, g_global_data.rsrv_offset), g_global_data.rsrv_size, 0, g_global_data.rsrv_size); + if(g_global_data.rsrv_size != 0) + { + memset_s(GET_PTR(void, enclave_base, g_global_data.rsrv_offset), g_global_data.rsrv_size, 0, g_global_data.rsrv_size); + } #endif // xsave uint64_t xfrm = get_xfeature_state();