diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ee9c48bb58bffe7f33f9fc3f540f664932e3e39..a14c482f41543e94bffa97c2a5cf2ac82acf891f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ if(ASAN_ENABLE) set(ASAN_OPTIONS "${ASAN_OPTION} -fsanitize=address -fsanitize-recover=address") endif(ASAN_ENABLE) -set(CMAKE_C_FLAGS "-fstack-protector-all -W -Wall -Werror -Wextra -Werror=array-bounds -D_FORTIFY_SOURCE=2 -O2 -ftrapv") +set(CMAKE_C_FLAGS "-fstack-protector-all -W -Wall -Werror -Wextra -Werror=array-bounds -D_FORTIFY_SOURCE=2 -O2 -ftrapv -Wno-deprecated-declarations") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_OPTION} ${ASAN_OPTIONS}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s") diff --git a/inc/common_inc/gp/gp_shared_memory_defs.h b/inc/common_inc/gp/gp_shared_memory_defs.h index 87c9a13187075bd329ea159744894ed0ce810a29..8af24118f8adca175c0c2b3721286be2e737f996 100644 --- a/inc/common_inc/gp/gp_shared_memory_defs.h +++ b/inc/common_inc/gp/gp_shared_memory_defs.h @@ -46,6 +46,7 @@ typedef struct { bool is_registered; // the shared memory can be used only after being registered void *enclave; // refer to cc_enclave_t pthread_t register_tid; + void *reg_session; // register shared memory by open session list_node_t node; } gp_shared_memory_t; diff --git a/inc/host_inc/enclave_internal.h b/inc/host_inc/enclave_internal.h index fa0cbf41300a68fe5773374481f32b6fe62db8e4..ac88f460fe104d63db3ea919ccaa5a38d7a84e8f 100644 --- a/inc/host_inc/enclave_internal.h +++ b/inc/host_inc/enclave_internal.h @@ -74,7 +74,7 @@ struct cc_enclave_ops { cc_enclave_result_t (*cc_sl_async_ecall_get_result)(cc_enclave_t *enclave, int task_id, void *retval); /* shared memory */ - void *(*cc_malloc_shared_memory)(cc_enclave_t *enclave, size_t size, bool is_control_buf); + void *(*cc_malloc_shared_memory)(cc_enclave_t *enclave, size_t size, bool is_control_buf, int try_cnt); cc_enclave_result_t (*cc_free_shared_memory)(cc_enclave_t *enclave, void *ptr); cc_enclave_result_t (*cc_register_shared_memory)(cc_enclave_t *enclave, void *ptr); cc_enclave_result_t (*cc_unregister_shared_memory)(cc_enclave_t *enclave, void *ptr); diff --git a/src/enclave_src/gp/gp.c b/src/enclave_src/gp/gp.c index 57c280feaf67456126db79867a3b1fdd4f826994..3f30a16d32f2bf411329a17ad63aaddd0b486d14 100644 --- a/src/enclave_src/gp/gp.c +++ b/src/enclave_src/gp/gp.c @@ -16,6 +16,8 @@ #include "tee_mem_mgmt_api.h" #include "gp.h" #include "caller.h" +#include "tee_log.h" +#include "itrustee/itrustee_shared_memory.h" #define PARAMNUM 4 #define POS_IN 0 diff --git a/src/enclave_src/gp/itrustee/CMakeLists.txt b/src/enclave_src/gp/itrustee/CMakeLists.txt index 14b3c642e6a4ac8d8a5b8e0de8b9bd5ef62dc40e..68ed4096fefd0a7979c64441c9d3b577fd810595 100644 --- a/src/enclave_src/gp/itrustee/CMakeLists.txt +++ b/src/enclave_src/gp/itrustee/CMakeLists.txt @@ -50,7 +50,8 @@ target_include_directories(${target_lib} PRIVATE ${LOCAL_ROOT_PATH}/inc/enclave_inc/gp/itrustee ${ITRUSTEE_TEEDIR}/include/CA ${LOCAL_ROOT_PATH}/inc/common_inc - ${LOCAL_ROOT_PATH}/inc/common_inc/gp) + ${LOCAL_ROOT_PATH}/inc/common_inc/gp + ${CMAKE_CURRENT_SOURCE_DIR}/) install(TARGETS ${target_lib} ARCHIVE diff --git a/src/enclave_src/gp/itrustee/itrustee_shared_memory.c b/src/enclave_src/gp/itrustee/itrustee_shared_memory.c index 32b8d8e93564a9bd986f059def36dd3f35a9d24a..09c8b7b91b984469f2dd969ece8fb25fb7688018 100644 --- a/src/enclave_src/gp/itrustee/itrustee_shared_memory.c +++ b/src/enclave_src/gp/itrustee/itrustee_shared_memory.c @@ -156,6 +156,41 @@ cc_enclave_result_t ecall_register_shared_memory(uint8_t *in_buf, return CC_SUCCESS; } +cc_enclave_result_t register_shared_memory_by_session(uint8_t *in_buf, uint8_t *registered_buf, void **sessionContext) +{ + /* Parse input parameters from in_buf */ + size_t in_buf_offset = size_to_aligned_size(sizeof(gp_register_shared_memory_size_t)); + gp_register_shared_memory_size_t *args_size = (gp_register_shared_memory_size_t *)in_buf; + + uint8_t *host_buf_p = NULL; + uint8_t *host_buf_len_p = NULL; + uint8_t *is_control_buf_p = NULL; + SET_PARAM_IN_1(host_buf_p, size_t, host_buf, args_size->shared_buf_size); + SET_PARAM_IN_1(host_buf_len_p, size_t, host_buf_len, args_size->shared_buf_len_size); + SET_PARAM_IN_1(is_control_buf_p, bool, is_control_buf, args_size->is_control_buf_size); + + cc_enclave_result_t ret = CC_FAIL; + + shared_memory_block_t *shared_mem = create_shared_memory_block((void *)host_buf, host_buf_len, registered_buf); + if (shared_mem == NULL) { + return CC_ERROR_OUT_OF_MEMORY; + } + + if (is_control_buf) { + ret = tswitchless_init((void *)shared_mem->enclave_addr, &shared_mem->pool, &shared_mem->tid_arr); + if (ret != CC_SUCCESS) { + destroy_shared_memory_block(shared_mem); + return CC_ERROR_TSWITCHLESS_INIT_FAILED; + } + } + + add_shared_memory_block_to_list(shared_mem); + __atomic_store_n(&(((gp_shared_memory_t *)registered_buf)->is_registered), true, __ATOMIC_RELEASE); + *sessionContext = (void *)shared_mem->enclave_addr; + + return CC_SUCCESS; +} + size_t addr_host_to_enclave(size_t host_addr) { list_node_t *cur = NULL; @@ -234,3 +269,30 @@ cc_enclave_result_t ecall_unregister_shared_memory(uint8_t *in_buf, return CC_SUCCESS; } + +void open_session_unregister_shared_memory(void *sessionContext) +{ + list_node_t *cur = NULL; + shared_memory_block_t *mem_block = NULL; + + CC_RWLOCK_LOCK_WR(&g_shared_memory_list_lock); + + list_for_each(cur, &g_shared_memory_list) { + mem_block = list_entry(cur, shared_memory_block_t, node); + tlogi("[secGear] unregister shared_mem:%p, cur_mem:%p", sessionContext, mem_block->enclave_addr); + if (sessionContext == (void *)mem_block->enclave_addr) { + __atomic_store_n(&((GP_SHARED_MEMORY_ENTRY(mem_block->enclave_addr))->is_registered), + false, __ATOMIC_RELEASE); + + list_remove(&mem_block->node); + if ((GP_SHARED_MEMORY_ENTRY(mem_block->enclave_addr))->is_control_buf) { + tswitchless_fini(mem_block->pool, mem_block->tid_arr); + } + destroy_shared_memory_block(mem_block); + break; + } + } + CC_RWLOCK_UNLOCK(&g_shared_memory_list_lock); + + return; +} diff --git a/src/enclave_src/gp/itrustee/itrustee_shared_memory.h b/src/enclave_src/gp/itrustee/itrustee_shared_memory.h new file mode 100644 index 0000000000000000000000000000000000000000..35ae829a58426bbe8464eaeb97fa995bd3de1725 --- /dev/null +++ b/src/enclave_src/gp/itrustee/itrustee_shared_memory.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * secGear is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef __ITRUSTEE_SHARED_MEMORY_H__ +#define __ITRUSTEE_SHARED_MEMORY_H__ + +#include "status.h" + +#ifdef __cplusplus +extern "C" { +#endif + +cc_enclave_result_t register_shared_memory_by_session(uint8_t *in_buf, uint8_t *registered_buf, void **sessionContext); +void open_session_unregister_shared_memory(void *sessionContext); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/host_src/gp/gp_enclave.c b/src/host_src/gp/gp_enclave.c index 952d584efc53f265bdcb07770870981475028a50..bad95336f27dc26a8906c748873d124843776599 100644 --- a/src/host_src/gp/gp_enclave.c +++ b/src/host_src/gp/gp_enclave.c @@ -377,27 +377,34 @@ cc_enclave_result_t init_uswitchless(cc_enclave_t *enclave, const enclave_featur uswitchless_adjust_config(&cfg); size_t pool_buf_len = sl_get_pool_buf_len_by_config(&cfg); - void *pool_buf = gp_malloc_shared_memory(enclave, pool_buf_len, true); - if (pool_buf == NULL) { - return CC_ERROR_OUT_OF_MEMORY; - } - (void)memset(pool_buf, 0, pool_buf_len); + cc_enclave_result_t ret; + sl_task_pool_t *pool; + for (int i = 0; i < 2; i++) { + void *pool_buf = gp_malloc_shared_memory(enclave, pool_buf_len, true, i); + if (pool_buf == NULL) { + return CC_ERROR_OUT_OF_MEMORY; + } + (void)memset(pool_buf, 0, pool_buf_len); - // Fill config - (void)memcpy(pool_buf, &cfg, sizeof(cc_sl_config_t)); + // Fill config + (void)memcpy(pool_buf, &cfg, sizeof(cc_sl_config_t)); - // Layout task pool - sl_task_pool_t *pool = uswitchless_create_task_pool(pool_buf, &cfg); - if (pool == NULL) { - (void)gp_free_shared_memory(enclave, pool_buf); - return CC_ERROR_OUT_OF_MEMORY; - } + // Layout task pool + pool = uswitchless_create_task_pool(pool_buf, &cfg); + if (pool == NULL) { + (void)gp_free_shared_memory(enclave, pool_buf); + return CC_ERROR_OUT_OF_MEMORY; + } - // Registering a task pool - cc_enclave_result_t ret = gp_register_shared_memory(enclave, pool_buf); - if (ret != CC_SUCCESS) { + // Registering a task pool + ret = gp_register_shared_memory(enclave, pool_buf); + if (ret == CC_SUCCESS) { + break; + } free(pool); (void)gp_free_shared_memory(enclave, pool_buf); + } + if (ret != CC_SUCCESS) { return ret; } @@ -698,6 +705,63 @@ cc_enclave_result_t handle_ecall_function_register_shared_memory(cc_enclave_t *e return CC_SUCCESS; } +/* TEEC_OpenSession 用户只能用param[0]和param[1], 2,3被底层默认占用了 */ +static cc_enclave_result_t init_open_session_register_memory_oper(TEEC_Operation *operation, + cc_enclave_call_function_args_t *args) +{ + const int input_pos = 0; + const int shared_pos = 1; + memset(operation, 0x00, sizeof(TEEC_Operation)); + operation->started = 1; + uint32_t paramtypes[] = { TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE }; + /* Fill input buffer */ + if (args->input_buffer_size) { + operation->params[input_pos].tmpref.buffer = (void *)args->input_buffer; + operation->params[input_pos].tmpref.size = (uint32_t)args->input_buffer_size; + paramtypes[input_pos] = TEEC_MEMREF_TEMP_INPUT; + } + + /* Fill shared buffer */ + gp_shared_memory_t *shared_mem = GP_SHARED_MEMORY_ENTRY(GET_HOST_BUF_FROM_INPUT_PARAMS(args->input_buffer)); + TEEC_SharedMemory *teec_shared_mem = (TEEC_SharedMemory *)(&shared_mem->shared_mem); + operation->params[shared_pos].memref.parent = teec_shared_mem; + operation->params[shared_pos].memref.size = teec_shared_mem->size; + paramtypes[shared_pos] = TEEC_MEMREF_REGISTER_INOUT; + + operation->paramTypes = TEEC_PARAM_TYPES(paramtypes[input_pos], paramtypes[shared_pos], TEEC_NONE, TEEC_NONE); + + return CC_SUCCESS; +} + +cc_enclave_result_t handle_open_session_register_shared_memory(cc_enclave_t *enclave, + cc_enclave_call_function_args_t *args, void *session) +{ + if (args->function_id == fid_register_shared_memory) { + gp_context_t *gp = (gp_context_t *)(enclave->private_data); + uint32_t origin; + TEEC_Operation oper; + memset(&oper, 0, sizeof(oper)); + oper.started = 1; + oper.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT); + cc_enclave_result_t cc_res = init_open_session_register_memory_oper(&oper, args); + if (cc_res != CC_SUCCESS) { + print_error_term("Handle ecall with new session, failed to init operation, ret:%x\n", cc_res); + return CC_FAIL; + } + TEEC_Result result = TEEC_OpenSession(&gp->ctx, session, &gp->uuid, TEEC_LOGIN_IDENTIFY, + NULL, &oper, &origin); + if (result != TEEC_SUCCESS) { + print_error_term("Handle ecall with new session, failed to open session, ret:%x, origin:%x\n", + result, origin); + cc_res = conversion_res_status(result, enclave->type); + return cc_res; + } + } else { // shared_mem->reg_session close by unregister shared memory + TEEC_CloseSession(session); + } + + return CC_SUCCESS; +} static cc_enclave_result_t handle_ecall_function(cc_enclave_t *enclave, cc_enclave_call_function_args_t *args) { @@ -706,7 +770,21 @@ static cc_enclave_result_t handle_ecall_function(cc_enclave_t *enclave, cc_encla TEEC_Operation operation; uint32_t origin; gp_context_t *gp = (gp_context_t*)enclave->private_data; - + if (args->function_id == fid_register_shared_memory || args->function_id == fid_unregister_shared_memory) { + gp_shared_memory_t *shared_mem = NULL; + if (args->function_id == fid_register_shared_memory) { + shared_mem = GP_SHARED_MEMORY_ENTRY(GET_HOST_BUF_FROM_INPUT_PARAMS(args->input_buffer)); + } else { + void *ptr = NULL; + (void)memcpy(&ptr, (char *)(args->input_buffer) + + size_to_aligned_size(sizeof(gp_unregister_shared_memory_size_t)), sizeof(void *)); + shared_mem = GP_SHARED_MEMORY_ENTRY(ptr); + } + TEEC_SharedMemory *teec_shared_mem = (TEEC_SharedMemory *)(&shared_mem->shared_mem); + if (teec_shared_mem->flags == TEEC_MEM_REGISTER_INOUT) { + return handle_open_session_register_shared_memory(enclave, args, shared_mem->reg_session); + } + } if (args->function_id == fid_register_shared_memory) { return handle_ecall_function_register_shared_memory(enclave, args); } diff --git a/src/host_src/gp/gp_shared_memory.c b/src/host_src/gp/gp_shared_memory.c index b6a958dbc3d6ccfe9d92aa1ef24cd18c9345bbfe..232edbfd9ce102fe38b045741a47fe41852ecb58 100644 --- a/src/host_src/gp/gp_shared_memory.c +++ b/src/host_src/gp/gp_shared_memory.c @@ -47,21 +47,33 @@ static void gp_add_shared_mem_to_list(gp_shared_memory_t *shared_mem) CC_RWLOCK_UNLOCK(&g_shared_mem_list_lock); } -void *gp_malloc_shared_memory(cc_enclave_t *context, size_t size, bool is_control_buf) +void *gp_malloc_shared_memory(cc_enclave_t *context, size_t size, bool is_control_buf, int try_cnt) { gp_context_t *gp_context = (gp_context_t *)context->private_data; gp_shared_memory_t gp_shared_mem = { .is_control_buf = is_control_buf, .is_registered = false, .enclave = (void *) context, - .register_tid = 0 + .register_tid = 0, + .reg_session = NULL }; + gp_shared_mem.reg_session = malloc(sizeof(TEEC_Session)); + if (gp_shared_mem.reg_session == NULL) { + return NULL; + } TEEC_SharedMemory *teec_shared_mem = (TEEC_SharedMemory *)(&gp_shared_mem.shared_mem); teec_shared_mem->size = size + sizeof(gp_shared_memory_t); - teec_shared_mem->flags = TEEC_MEM_SHARED_INOUT; + teec_shared_mem->flags = try_cnt == 0 ? TEEC_MEM_REGISTER_INOUT : TEEC_MEM_SHARED_INOUT; TEEC_Result result = TEEC_AllocateSharedMemory(&gp_context->ctx, teec_shared_mem); + if (result == TEEC_ERROR_BAD_PARAMETERS) { + print_warning("not support register type, try shared type again.\n"); + teec_shared_mem->flags = TEEC_MEM_SHARED_INOUT; + result = TEEC_AllocateSharedMemory(&gp_context->ctx, teec_shared_mem); + } + if (result != TEEC_SUCCESS) { + free(gp_shared_mem.reg_session); return NULL; } @@ -106,6 +118,10 @@ cc_enclave_result_t gp_free_shared_memory(cc_enclave_t *enclave, void *ptr) } gp_remove_shared_mem_from_list(GP_SHARED_MEMORY_ENTRY(ptr)); + if (GP_SHARED_MEMORY_ENTRY(ptr)->reg_session != NULL) { + free(GP_SHARED_MEMORY_ENTRY(ptr)->reg_session); + GP_SHARED_MEMORY_ENTRY(ptr)->reg_session = NULL; + } TEEC_SharedMemory sharedMem = *TEEC_SHARED_MEMORY_ENTRY(ptr); TEEC_ReleaseSharedMemory(&sharedMem); diff --git a/src/host_src/gp/gp_shared_memory.h b/src/host_src/gp/gp_shared_memory.h index 6914193818698d2a1b66ad7f2e996104c6495453..4659b4a24350e060cb6fbc262c050b50b2afb755 100644 --- a/src/host_src/gp/gp_shared_memory.h +++ b/src/host_src/gp/gp_shared_memory.h @@ -31,7 +31,7 @@ extern "C" { * is_control_buf: whether it is a control area buffer * Return: A pointer to the allocated memory. On error, return NULL. */ -void *gp_malloc_shared_memory(cc_enclave_t *context, size_t size, bool is_control_buf); +void *gp_malloc_shared_memory(cc_enclave_t *context, size_t size, bool is_control_buf, int try_cnt); /* * Summary: Frees the memory space pointed to by ptr, which must have been returned by gp_malloc_shared_memory. diff --git a/src/host_src/secgear_shared_memory.c b/src/host_src/secgear_shared_memory.c index d7e8d35e831767229b8721966e324bd662f3e127..258f329a43598c5d2e4722e52d2f82bc42a54913 100644 --- a/src/host_src/secgear_shared_memory.c +++ b/src/host_src/secgear_shared_memory.c @@ -40,21 +40,27 @@ void *cc_malloc_shared_memory(cc_enclave_t *enclave, size_t size) return NULL; } - void *ptr = FUNC_CREATE_SHARED_MEM(enclave)(enclave, size, false); - if (ptr == NULL) { - CC_RWLOCK_UNLOCK(&enclave->rwlock); - return NULL; + cc_enclave_result_t ret; + void *ptr; + for (int i = 0; i < 2; i++) { + ptr = FUNC_CREATE_SHARED_MEM(enclave)(enclave, size, false, i); + if (ptr == NULL) { + CC_RWLOCK_UNLOCK(&enclave->rwlock); + return NULL; + } + + ret = FUNC_REGISTER_SHARED_MEM(enclave)(enclave, ptr); + if (ret == CC_SUCCESS) { + break; + } + CC_IGNORE(FUNC_FREE_SHARED_MEM(enclave)(enclave, ptr)); } - cc_enclave_result_t ret = FUNC_REGISTER_SHARED_MEM(enclave)(enclave, ptr); + CC_RWLOCK_UNLOCK(&enclave->rwlock); if (ret != CC_SUCCESS) { - CC_IGNORE(FUNC_FREE_SHARED_MEM(enclave)(enclave, ptr)); - CC_RWLOCK_UNLOCK(&enclave->rwlock); return NULL; } - CC_RWLOCK_UNLOCK(&enclave->rwlock); - return ptr; } diff --git a/src/host_src/sgx/sgx_shared_memory.c b/src/host_src/sgx/sgx_shared_memory.c index b9ecf9a8872b7f33a6406355be87885307535821..269958055754dbfa332f791e838f969cd4c9d1b3 100644 --- a/src/host_src/sgx/sgx_shared_memory.c +++ b/src/host_src/sgx/sgx_shared_memory.c @@ -15,10 +15,11 @@ #include #include "secgear_defs.h" -void *sgx_malloc_shared_memory(cc_enclave_t *enclave, size_t size, bool is_control_buf) +void *sgx_malloc_shared_memory(cc_enclave_t *enclave, size_t size, bool is_control_buf, int try_cnt) { CC_IGNORE(enclave); CC_IGNORE(is_control_buf); + CC_IGNORE(try_cnt); return malloc(size); } diff --git a/src/host_src/sgx/sgx_shared_memory.h b/src/host_src/sgx/sgx_shared_memory.h index 861cea7ddfc01207efbd64652d1faeba76dd4e1f..b7f886a136f794d155b6de02b48066844a0a6dc4 100644 --- a/src/host_src/sgx/sgx_shared_memory.h +++ b/src/host_src/sgx/sgx_shared_memory.h @@ -27,7 +27,7 @@ * is_control_buf: whether it is a control area buffer * Return: A pointer to the allocated memory. On error, return NULL. */ -void *sgx_malloc_shared_memory(cc_enclave_t *context, size_t size, bool is_control_buf); +void *sgx_malloc_shared_memory(cc_enclave_t *context, size_t size, bool is_control_buf, int try_cnt); /* * Summary: Frees the memory space pointed to by ptr, which must have been returned by sgx_malloc_shared_memory.