• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #include "tee_operation.h"
14 #include <dlist.h>
15 #include <tee_log.h>
16 #include <pthread.h>
17 #include <errno.h>
18 
19 #define LOCK_UNLOCK_OK 0
20 static dlist_head(g_operation_list);
21 static pthread_mutex_t g_operation_mutex = PTHREAD_MUTEX_INITIALIZER;
22 
23 typedef struct {
24     struct dlist_node list_node;
25     TEE_OperationHandle operation;
26 } operation_node;
27 
operation_lock_ops(pthread_mutex_t * mtx)28 static int32_t operation_lock_ops(pthread_mutex_t *mtx)
29 {
30     int32_t ret = pthread_mutex_lock(mtx);
31     if (ret == EOWNERDEAD) /* owner died, use consistent to recover and lock the mutex */
32         return pthread_mutex_consistent(mtx);
33 
34     return ret;
35 }
36 
add_operation(TEE_OperationHandle operation)37 TEE_Result add_operation(TEE_OperationHandle operation)
38 {
39     if (operation == NULL) {
40         tloge("The operation is NULL\n");
41         return TEE_ERROR_BAD_PARAMETERS;
42     }
43 
44     operation_node *valid_operation = TEE_Malloc(sizeof(*valid_operation), TEE_MALLOC_FILL_ZERO);
45     if (valid_operation == NULL) {
46         tloge("Malloc operation node failed\n");
47         return TEE_ERROR_OUT_OF_MEMORY;
48     }
49     valid_operation->operation = operation;
50 
51     if (operation_lock_ops(&g_operation_mutex) != LOCK_UNLOCK_OK) {
52         tloge("Lock operation mutex failed\n");
53         TEE_Free(valid_operation);
54         return TEE_ERROR_GENERIC;
55     }
56     dlist_insert_head(&(valid_operation->list_node), &g_operation_list);
57     if (pthread_mutex_unlock(&g_operation_mutex) != LOCK_UNLOCK_OK) {
58         tloge("Unlock operation mutex failed\n");
59         dlist_delete(&(valid_operation->list_node));
60         TEE_Free(valid_operation);
61         return TEE_ERROR_GENERIC;
62     }
63 
64     return TEE_SUCCESS;
65 }
66 
delete_operation(const TEE_OperationHandle operation)67 void delete_operation(const TEE_OperationHandle operation)
68 {
69     if (operation == NULL)
70         return;
71 
72     operation_node *valid_operation = NULL;
73     operation_node *tmp             = NULL;
74 
75     if (operation_lock_ops(&g_operation_mutex) != LOCK_UNLOCK_OK) {
76         tloge("Lock operation mutex failed\n");
77         return;
78     }
79 
80     dlist_for_each_entry_safe(valid_operation, tmp, &g_operation_list, operation_node, list_node) {
81         if (valid_operation->operation == operation) {
82             dlist_delete(&(valid_operation->list_node));
83             TEE_Free(valid_operation);
84             valid_operation = NULL;
85             break;
86         }
87     }
88     if (pthread_mutex_unlock(&g_operation_mutex) != LOCK_UNLOCK_OK) {
89         tloge("Unlock operation mutex failed\n");
90         return;
91     }
92 
93     return;
94 }
95 
check_operation(const TEE_OperationHandle operation)96 TEE_Result check_operation(const TEE_OperationHandle operation)
97 {
98     TEE_Result ret                  = TEE_ERROR_GENERIC;
99     operation_node *valid_operation = NULL;
100 
101     if (operation == NULL)
102         return TEE_ERROR_BAD_PARAMETERS;
103 
104     if (operation_lock_ops(&g_operation_mutex) != LOCK_UNLOCK_OK) {
105         tloge("Lock operation mutex failed\n");
106         return TEE_ERROR_GENERIC;
107     }
108 
109     dlist_for_each_entry(valid_operation, &g_operation_list, operation_node, list_node) {
110         if (valid_operation->operation == operation) {
111             ret = TEE_SUCCESS;
112             break;
113         }
114     }
115 
116     if (pthread_mutex_unlock(&g_operation_mutex) != LOCK_UNLOCK_OK) {
117         tloge("Unlock operation mutex failed\n");
118         return TEE_ERROR_GENERIC;
119     }
120 
121     return ret;
122 }
123