From 1680c15af6226a8a205f37162e54dc85a3dfc2b0 Mon Sep 17 00:00:00 2001
From: chenmaodong <chenmaodong@huawei.com>
Date: Wed, 17 Mar 2021 12:34:24 +0800
Subject: 1.fix the race of ecall and enclave destroy 2.add a used flag for
 context in case of double destroy or double create

Signed-off-by: chenmaodong <chenmaodong@huawei.com>
---
 environment                    |  3 ++-
 inc/host_inc/enclave.h         |  4 +++-
 src/host_src/CMakeLists.txt    |  4 ++--
 src/host_src/enclave.c         | 14 +++++++++++---
 src/host_src/sgx/sgx_enclave.c |  2 ++
 5 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/environment b/environment
index a45ff9e..c438449 100644
--- a/environment
+++ b/environment
@@ -1,2 +1,3 @@
-export CC_SDK=$(pwd)
+file_dir=`readlink -f ${BASH_SOURCE[0]}`
+export CC_SDK=`dirname $file_dir`
 export PATH=$PATH:$CC_SDK/bin/
diff --git a/inc/host_inc/enclave.h b/inc/host_inc/enclave.h
index b063ce9..ca9e8da 100644
--- a/inc/host_inc/enclave.h
+++ b/inc/host_inc/enclave.h
@@ -16,7 +16,7 @@
 #include <stdint.h>
 #include <stddef.h>
 #include <stdbool.h>
-
+#include <pthread.h>
 
 #include "status.h"
 
@@ -62,6 +62,8 @@ typedef struct _enclave {
     enclave_type_version_t type;
     char *path;
     uint32_t flags;
+    pthread_rwlock_t rwlock;
+    bool used_flag;
     void *private_data;
     /*enclave engine context manage, only one pointer*/
     struct  list_ops_desc *list_ops_node;
diff --git a/src/host_src/CMakeLists.txt b/src/host_src/CMakeLists.txt
index df4d3bf..25d245f 100644
--- a/src/host_src/CMakeLists.txt
+++ b/src/host_src/CMakeLists.txt
@@ -25,8 +25,8 @@ endif()
 add_library(secgear SHARED enclave.c enclave_internal.c ocall_log.c enclave_ocall.c)
 add_library(secgearsim SHARED enclave.c enclave_internal.c ocall_log.c enclave_ocall.c)
 
-target_link_libraries(secgear dl)
-target_link_libraries(secgearsim dl)
+target_link_libraries(secgear dl pthread)
+target_link_libraries(secgearsim dl pthread)
 
 set_target_properties(secgear PROPERTIES 
             SKIP_BUILD_RPATH TRUE)
diff --git a/src/host_src/enclave.c b/src/host_src/enclave.c
index dc8c5ed..204c808 100644
--- a/src/host_src/enclave.c
+++ b/src/host_src/enclave.c
@@ -109,7 +109,7 @@ done:
 static bool check_flag(cc_enclave_result_t *res, const char *path, uint32_t flags, const enclave_features_t *features,
     const uint32_t features_count, cc_enclave_t **enclave)
 {
-    if (enclave == NULL || *enclave != NULL) {
+    if (enclave == NULL || (*enclave != NULL && (*enclave)->used_flag == true)) {
         *res = CC_ERROR_INVALID_ENCLAVE_ID;
         return false;
     }
@@ -217,11 +217,14 @@ cc_enclave_result_t cc_enclave_create(const char *path, enclave_type_t type, uin
     if (((GP_ENCLAVE_TYPE_0 <= type_version) && (type_version < GP_ENCLAVE_TYPE_MAX)) && (flags & SECGEAR_DEBUG_FLAG)) {
         print_warning("This enclave scheme does not support enter enclave debugging\n");
     }    
-
+    
     /* initialize the context */
+
+    pthread_rwlock_init(&(l_context->rwlock), NULL);
     l_context->path  = l_path;
     l_context->flags = flags;
     l_context->type  = type_version;
+    l_context->used_flag = true;
 
     /* if an enclave is created multiple times, first find it in the global list,
      * maybe the information about this engine has been filled in the list 
@@ -280,11 +283,13 @@ cc_enclave_result_t cc_enclave_destroy(cc_enclave_t *context)
     p_tee_unregistered unregistered_funcc;
 
     /* check context and enclave engine context */
-    if (!context || !context->list_ops_node) {
+    if (!context || !context->list_ops_node || !context->list_ops_node->ops_desc ||
+        !context->list_ops_node->ops_desc->ops || context->used_flag == false) {
         print_error_term("Function context parameter error\n");
         return CC_ERROR_BAD_PARAMETERS;
     }
 
+    pthread_rwlock_wrlock(&(context->rwlock));
     if (context->list_ops_node->ops_desc->ops->cc_destroy_enclave != NULL) {
         res = context->list_ops_node->ops_desc->ops->cc_destroy_enclave(context);
         SECGEAR_CHECK_RES(res);
@@ -322,6 +327,9 @@ done:
         free(context->path);
     }
     if (context) {
+        pthread_rwlock_unlock(&context->rwlock);
+        pthread_rwlock_destroy(&context->rwlock);
+        explicit_bzero(context, sizeof(cc_enclave_t));
         free(context);
     }
     return res;
diff --git a/src/host_src/sgx/sgx_enclave.c b/src/host_src/sgx/sgx_enclave.c
index a40c408..258c58a 100644
--- a/src/host_src/sgx/sgx_enclave.c
+++ b/src/host_src/sgx/sgx_enclave.c
@@ -200,8 +200,10 @@ cc_enclave_result_t cc_enclave_sgx_call_function(
     (void)output_buffer_size;
     sgx_status_t status;
     cc_enclave_result_t cc_status;
+    pthread_rwlock_rdlock(&(enclave->rwlock));
     status = sgx_ecall(((sgx_context_t *)(enclave->private_data))->edi, (int)function_id, ocall_table, ms);
     cc_status = conversion_res_status(status, enclave->type);
+    pthread_rwlock_unlock(&(enclave->rwlock));
     return cc_status;
 }
  
-- 
1.8.3.1

