Core: Detect the current handling handle in psa_close

When the connection is currently handling a request, the
psa_close should call tfm_panic().

Change-Id: Ic29c0dea33c11c97616086490d26e034a8b8cb11
Signed-off-by: Shawn Shan <shawn.shan@arm.com>
diff --git a/secure_fw/core/ipc/tfm_psa_client_call.c b/secure_fw/core/ipc/tfm_psa_client_call.c
index 56da86a..668a262 100644
--- a/secure_fw/core/ipc/tfm_psa_client_call.c
+++ b/secure_fw/core/ipc/tfm_psa_client_call.c
@@ -210,7 +210,7 @@
 
     /*
      * It is a fatal error if an invalid handle was provided that is not the
-     * null handle..
+     * null handle.
      */
     service = tfm_spm_get_service_by_handle(handle);
     if (!service) {
@@ -224,6 +224,12 @@
         tfm_panic();
     }
 
+    /* It is a fatal error if the connection is currently handling a request. */
+    if(((struct tfm_conn_handle_t *)handle)->status ==
+                                                     TFM_HANDLE_STATUS_ACTIVE) {
+        tfm_panic();
+    }
+
     /* No input or output needed for close message */
     tfm_spm_fill_msg(msg, service, handle, PSA_IPC_DISCONNECT, ns_caller,
                      NULL, 0, NULL, 0, NULL);
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
index 66fafd4..bde97ff 100644
--- a/secure_fw/core/ipc/tfm_svcalls.c
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -301,6 +301,9 @@
         return PSA_ERROR_DOES_NOT_EXIST;
     }
 
+    ((struct tfm_conn_handle_t *)(tmp_msg->handle))->status =
+                                                       TFM_HANDLE_STATUS_ACTIVE;
+
     tfm_core_util_memcpy(msg, &tmp_msg->msg, sizeof(psa_msg_t));
 
     /*
@@ -709,6 +712,9 @@
         }
     }
 
+    ((struct tfm_conn_handle_t *)(msg->handle))->status =
+                                                         TFM_HANDLE_STATUS_IDLE;
+
     if (is_tfm_rpc_msg(msg)) {
         tfm_rpc_client_call_reply(NULL, ret);
     } else {
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index e1de88d..9929b3c 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -48,6 +48,9 @@
 #define SPM_PART_FLAG_PSA_ROT 0x02
 #define SPM_PART_FLAG_IPC     0x04
 
+#define TFM_HANDLE_STATUS_IDLE          0
+#define TFM_HANDLE_STATUS_ACTIVE        1
+
 #ifndef TFM_PSA_API
 /**
  * \brief Holds the iovec parameters that are passed to a service
@@ -115,6 +118,11 @@
 /* RoT connection handle list */
 struct tfm_conn_handle_t {
     void *rhandle;                      /* Reverse handle value              */
+    uint32_t status;                    /*
+                                         * Status of handle, two valid options:
+                                         * TFM_HANDLE_STATUS_ACTIVE and
+                                         * TFM_HANDLE_STATUS_IDLE
+                                         */
     struct tfm_msg_body_t internal_msg; /* Internal message for message queue */
     struct tfm_spm_service_t *service;  /* RoT service pointer               */
     struct tfm_list_node_t list;        /* list node                         */
@@ -127,8 +135,8 @@
     psa_signal_t signal;            /* Service signal                        */
     uint32_t sid;                   /* Service identifier                    */
     bool non_secure_client;         /* If can be called by non secure client */
-    uint32_t version;               /* Service version                         */
-    uint32_t version_policy;        /* Service version policy                  */
+    uint32_t version;               /* Service version                       */
+    uint32_t version_policy;        /* Service version policy                */
 };
 
 /* RoT Service data */
diff --git a/secure_fw/spm/spm_api_ipc.c b/secure_fw/spm/spm_api_ipc.c
index 7b08682..58a0fd3 100644
--- a/secure_fw/spm/spm_api_ipc.c
+++ b/secure_fw/spm/spm_api_ipc.c
@@ -63,6 +63,7 @@
     }
 
     p_handle->service = service;
+    p_handle->status = TFM_HANDLE_STATUS_IDLE;
 
     /* Add handle node to list for next psa functions */
     tfm_list_add_tail(&service->handle_list, &p_handle->list);