• 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_core_api.h"
14 #include <pthread.h>
15 #include <securec.h>
16 #include <dlist.h>
17 #include <mem_ops.h>
18 #include <ipclib.h>
19 #include <ipclib_hal.h>
20 #include "tee_mem_mgmt_api.h"
21 #include "ta_framework.h"
22 #include "tee_log.h"
23 #include "tee_bitmap.h"
24 #include "tee_init.h"
25 #include "securec.h"
26 #include "tee_ta2ta.h"
27 #include "tee_secfile_load_agent.h"
28 #include "tee_inner_uuid.h"
29 
30 #define TASK_SHARE_MEM_PT_NO 0x2
31 #define OFFSET               7U
32 #define MOVE_BIT             3
33 #define MOVE_OFFSET          32
34 #define MEMORY_OFFSET        4
35 #define MEMORY_MASK          3
36 #define COREAPI_ADDR_MASK    0xFFFFFFFF
37 #define MUTEX_SUCC_RET       0 /* mutex operation will return 0 when it succ */
38 
39 struct ta2ta_session_handle {
40     TEE_TASessionHandle handle;
41     TEE_UUID uuid;
42     uint32_t session_id;
43     uint32_t src_tid;
44     struct dlist_node list;
45 };
46 
47 struct ta2ta_smc_call_params {
48     uint32_t call_type;
49     const TEE_UUID *uuid;
50     uint32_t session_id;
51     uint32_t command_id;
52     uint32_t param_types;
53     TEE_Param *params;
54     TEE_TASessionHandle *handle;
55 };
56 
57 static dlist_head(g_handle_head);
58 static uint8_t g_handle_bitmap[(HANDLE_MAX + OFFSET) >> MOVE_BIT];
59 
60 struct cancel_state_struct {
61     uint32_t session_id;
62     bool mask;
63     bool flag;
64     struct dlist_node list;
65 };
66 
67 struct ret_vaild_handle {
68     TEE_Result ret;
69     TEE_TASessionHandle valid_handle;
70 };
71 
72 static dlist_head(g_session_cancel_state);
73 static pthread_mutex_t g_global_mutex = PTHREAD_MUTEX_INITIALIZER;
74 
mutex_lock_ops(pthread_mutex_t * mtx)75 static int32_t mutex_lock_ops(pthread_mutex_t *mtx)
76 {
77     int32_t ret = pthread_mutex_lock(mtx);
78     if (ret == EOWNERDEAD) /* owner died, use consistent to recover and lock the mutex */
79         return pthread_mutex_consistent(mtx);
80 
81     return ret;
82 }
83 
84 /* add session tls info begin */
85 static dlist_head(g_tls_info);
86 
add_tls_info(struct running_info * info)87 void add_tls_info(struct running_info *info)
88 {
89     struct tls_info *tls = NULL;
90     int32_t ret;
91 
92     if (info == NULL) {
93         tloge("invalid info\n");
94         return;
95     }
96 
97     tls = TEE_Malloc(sizeof(*tls), 0);
98     if (tls == NULL) {
99         tloge("alloc tls info failed\n");
100         return;
101     }
102     tls->info = info;
103 
104     ret = mutex_lock_ops(&g_global_mutex);
105     if (ret != MUTEX_SUCC_RET) {
106         tloge("mutex lock failed with ret %d\n", ret);
107         tls->info = NULL;
108         TEE_Free(tls);
109         return;
110     }
111 
112     dlist_insert_tail(&tls->list, &g_tls_info);
113 
114     ret = pthread_mutex_unlock(&g_global_mutex);
115     if (ret != MUTEX_SUCC_RET)
116         tloge("mutex unlock failed with ret %d\n", ret);
117 }
118 
delete_tls_info(uint32_t session_id)119 void delete_tls_info(uint32_t session_id)
120 {
121     struct tls_info *info    = NULL;
122     struct running_info *tls = NULL;
123     bool find                = false;
124 
125     int32_t ret = mutex_lock_ops(&g_global_mutex);
126     if (ret != MUTEX_SUCC_RET) {
127         tloge("mutex lock failed with ret %d\n", ret);
128         return;
129     }
130 
131     dlist_for_each_entry(info, &g_tls_info, struct tls_info, list) {
132         tls = info->info;
133         if ((tls != NULL) && (tls->session_id == session_id)) {
134             find = true;
135             break;
136         }
137     }
138 
139     if (find) {
140         dlist_delete(&info->list);
141         if (memset_s(tls, sizeof(*tls), 0, sizeof(*tls)) != EOK)
142             tloge("memset tls failed\n");
143         TEE_Free(tls);
144         tls        = NULL;
145         info->info = NULL;
146         TEE_Free(info);
147         info = NULL;
148     }
149 
150     ret = pthread_mutex_unlock(&g_global_mutex);
151     if (ret != MUTEX_SUCC_RET)
152         tloge("mutex unlock failed with ret %d\n", ret);
153 }
154 
155 /* add session tls info end */
get_session_cancel_state(uint32_t session_id)156 static struct cancel_state_struct *get_session_cancel_state(uint32_t session_id)
157 {
158     struct cancel_state_struct *state = NULL;
159 
160     dlist_for_each_entry(state, &g_session_cancel_state, struct cancel_state_struct, list) {
161         if (state->session_id == session_id)
162             return state;
163     }
164 
165     /* should get here */
166     tloge("get cancel state failed!\n");
167 
168     return NULL;
169 }
170 
add_session_cancel_state(uint32_t session_id)171 void add_session_cancel_state(uint32_t session_id)
172 {
173     struct cancel_state_struct *cancel_state = NULL;
174     int32_t ret;
175 
176     cancel_state = TEE_Malloc(sizeof(*cancel_state), 0);
177     if (cancel_state == NULL) {
178         tloge("alloc cancel state failed\n");
179         return;
180     }
181     cancel_state->session_id = session_id;
182     cancel_state->mask       = true;
183     cancel_state->flag       = false;
184 
185     ret = mutex_lock_ops(&g_global_mutex);
186     if (ret != MUTEX_SUCC_RET) {
187         tloge("mutex lock failed with ret %d\n", ret);
188         TEE_Free(cancel_state);
189         return;
190     }
191     dlist_insert_tail(&cancel_state->list, &g_session_cancel_state);
192 
193     ret = pthread_mutex_unlock(&g_global_mutex);
194     if (ret != MUTEX_SUCC_RET)
195         tloge("mutex unlock failed with ret %d\n", ret);
196 }
197 
del_session_cancel_state(uint32_t session_id)198 void del_session_cancel_state(uint32_t session_id)
199 {
200     struct cancel_state_struct *state = NULL;
201     int32_t ret                       = mutex_lock_ops(&g_global_mutex);
202     if (ret != MUTEX_SUCC_RET) {
203         tloge("mutex lock failed with ret %d\n", ret);
204         return;
205     }
206 
207     dlist_for_each_entry(state, &g_session_cancel_state, struct cancel_state_struct, list) {
208         if (state->session_id == session_id) {
209             dlist_delete(&state->list);
210             ret = pthread_mutex_unlock(&g_global_mutex);
211             if (ret != MUTEX_SUCC_RET)
212                 tloge("mutex unlock failed with ret %d\n", ret);
213 
214             TEE_Free(state);
215             return;
216         }
217     }
218 
219     ret = pthread_mutex_unlock(&g_global_mutex);
220     if (ret != MUTEX_SUCC_RET)
221         tloge("mutex unlock failed with ret %d\n", ret);
222 }
223 
set_session_cancel_flag(bool flag)224 void set_session_cancel_flag(bool flag)
225 {
226     int32_t ret = mutex_lock_ops(&g_global_mutex);
227     if (ret != MUTEX_SUCC_RET) {
228         tloge("mutex lock failed with ret %d\n", ret);
229         return;
230     }
231 
232     struct cancel_state_struct *state = get_session_cancel_state(get_current_session_id());
233     if (state != NULL)
234         state->flag = flag;
235 
236     ret = pthread_mutex_unlock(&g_global_mutex);
237     if (ret != MUTEX_SUCC_RET)
238         tloge("mutex unlock failed with ret %d\n", ret);
239 }
240 
TEE_Panic(TEE_Result panicCode)241 void TEE_Panic(TEE_Result panicCode)
242 {
243     PARAM_NOT_USED(panicCode);
244     tloge("TEE Panic with panicCode 0x%x\n", panicCode);
245     // abort();
246 }
247 
init_tee_internal_api(void)248 void init_tee_internal_api(void)
249 {
250     set_bitmap(g_handle_bitmap, HANDLE_MAX, 0);
251 }
252 
new_ta2ta_session_handle(TEE_TASessionHandle * handle)253 static TEE_Result new_ta2ta_session_handle(TEE_TASessionHandle *handle)
254 {
255     struct ta2ta_session_handle *session_handle = NULL;
256     int32_t valid_handle;
257     uint32_t task_id;
258     int32_t ret;
259 
260     session_handle = TEE_Malloc(sizeof(*session_handle), 0);
261     if (session_handle == NULL) {
262         tloge("alloc session handle failed\n");
263         return TEE_ERROR_OUT_OF_MEMORY;
264     }
265 
266     ret = mutex_lock_ops(&g_global_mutex);
267     if (ret != MUTEX_SUCC_RET) {
268         tloge("mutex lock failed with ret %d\n", ret);
269         TEE_Free(session_handle);
270         return TEE_ERROR_GENERIC;
271     }
272 
273     valid_handle = get_valid_bit(g_handle_bitmap, HANDLE_MAX);
274     if (valid_handle == -1) { /* -1 means invalid handle */
275         ret = pthread_mutex_unlock(&g_global_mutex);
276         if (ret != MUTEX_SUCC_RET)
277             tloge("mutex unlock failed with ret %d\n", ret);
278 
279         TEE_Free(session_handle);
280         return TEE_ERROR_OUT_OF_MEMORY;
281     }
282 
283     session_handle->handle = (TEE_TASessionHandle)valid_handle;
284     task_id = get_self_taskid();
285     if (task_id < 0) {
286         tloge("get taskid failed\n");
287         TEE_Free(session_handle);
288 
289         ret = pthread_mutex_unlock(&g_global_mutex);
290         if (ret != MUTEX_SUCC_RET)
291             tloge("mutex unlock failed with ret %d\n", ret);
292 
293         return TEE_ERROR_GENERIC;
294     }
295 
296     session_handle->src_tid = taskid_to_tid(task_id);
297     dlist_init(&session_handle->list);
298 
299     set_bitmap(g_handle_bitmap, HANDLE_MAX, valid_handle);
300     dlist_insert_tail(&session_handle->list, &g_handle_head);
301 
302     ret = pthread_mutex_unlock(&g_global_mutex);
303     if (ret != MUTEX_SUCC_RET)
304         tloge("mutex unlock failed with ret %d\n", ret);
305 
306     *handle = valid_handle;
307 
308     return TEE_SUCCESS;
309 }
310 
set_ta2ta_session_handle(const TEE_UUID * uuid,uint32_t session_id,TEE_TASessionHandle handle)311 static TEE_Result set_ta2ta_session_handle(const TEE_UUID *uuid, uint32_t session_id, TEE_TASessionHandle handle)
312 {
313     struct ta2ta_session_handle *s_handle = NULL;
314     bool find                             = false;
315     TEE_Result s_ret                      = TEE_ERROR_GENERIC;
316 
317     int32_t ret = mutex_lock_ops(&g_global_mutex);
318     if (ret != MUTEX_SUCC_RET) {
319         tloge("mutex lock failed with ret %d\n", ret);
320         return s_ret;
321     }
322 
323     dlist_for_each_entry(s_handle, &g_handle_head, struct ta2ta_session_handle, list) {
324         if (s_handle->handle == handle) {
325             find = true;
326             break;
327         }
328     }
329 
330     if (find) {
331         if (uuid == NULL) {
332             clear_bitmap(g_handle_bitmap, HANDLE_MAX, s_handle->handle);
333             tlogd("find handle session_handle:0x%x\n", handle);
334             dlist_delete(&s_handle->list);
335             TEE_Free(s_handle);
336             s_handle = NULL;
337             s_ret    = TEE_SUCCESS;
338         } else {
339             s_handle->session_id = session_id;
340             s_handle->uuid       = *uuid;
341             s_ret                = TEE_SUCCESS;
342         }
343     }
344 
345     ret = pthread_mutex_unlock(&g_global_mutex);
346     if (ret != MUTEX_SUCC_RET)
347         tloge("mutex unlock failed with ret %d\n", ret);
348 
349     return s_ret;
350 }
351 
delete_ta2ta_session_id(TEE_TASessionHandle session_handle)352 static void delete_ta2ta_session_id(TEE_TASessionHandle session_handle)
353 {
354     /* input param NULL/0 will clear all mem */
355     if (set_ta2ta_session_handle(NULL, 0, session_handle) != TEE_SUCCESS)
356         tloge("delete ta session failed\n");
357 }
358 
get_ta2ta_session_handle(TEE_TASessionHandle handle,struct ta2ta_session_handle ** session_handle)359 static TEE_Result get_ta2ta_session_handle(TEE_TASessionHandle handle, struct ta2ta_session_handle **session_handle)
360 {
361     struct ta2ta_session_handle *s_handle = NULL;
362     int32_t ret;
363 
364     if (session_handle == NULL)
365         return TEE_ERROR_BAD_PARAMETERS;
366 
367     ret = mutex_lock_ops(&g_global_mutex);
368     if (ret != MUTEX_SUCC_RET) {
369         tloge("mutex lock failed with ret %d\n", ret);
370         return TEE_ERROR_GENERIC;
371     }
372 
373     if (!is_bit_seted(g_handle_bitmap, HANDLE_MAX, handle)) {
374         ret = pthread_mutex_unlock(&g_global_mutex);
375         if (ret != MUTEX_SUCC_RET)
376             tloge("mutex unlock failed with ret %d\n", ret);
377 
378         return TEE_ERROR_ITEM_NOT_FOUND;
379     }
380 
381     dlist_for_each_entry(s_handle, &g_handle_head, struct ta2ta_session_handle, list) {
382         if (s_handle->handle == handle) {
383             *session_handle = s_handle;
384             ret             = pthread_mutex_unlock(&g_global_mutex);
385             if (ret != MUTEX_SUCC_RET)
386                 tloge("mutex unlock failed with ret %d\n", ret);
387 
388             return TEE_SUCCESS;
389         }
390     }
391     ret = pthread_mutex_unlock(&g_global_mutex);
392     if (ret != MUTEX_SUCC_RET)
393         tloge("mutex unlock failed with ret %d\n", ret);
394 
395     return TEE_ERROR_ITEM_NOT_FOUND;
396 }
397 
alloc_sharemem(uint32_t size)398 static void *alloc_sharemem(uint32_t size)
399 {
400     TEE_UUID gtask_uuid = TEE_SERVICE_GLOBAL;
401     return alloc_sharemem_aux(&gtask_uuid, size);
402 }
403 
common_free_sharemem(const int8_t * addr,int32_t size)404 static void common_free_sharemem(const int8_t *addr, int32_t size)
405 {
406     if (free_sharemem((void *)addr, size) != 0) /* 0 means success */
407         tloge("free share memory fail\n");
408 }
409 
push_params_check(const TEE_Param * params,const struct smc_operation * operation)410 static inline TEE_Result push_params_check(const TEE_Param *params, const struct smc_operation *operation)
411 {
412     if (params == NULL || operation == NULL)
413         return TEE_ERROR_BAD_PARAMETERS;
414 
415     return TEE_SUCCESS;
416 }
417 
handle_mem_buffer(uint32_t i,const TEE_Param * params,struct smc_operation * operation,int8_t ** buf)418 static TEE_Result handle_mem_buffer(uint32_t i, const TEE_Param *params, struct smc_operation *operation, int8_t **buf)
419 {
420     if (params[i].memref.size > UINT32_MAX) {
421         tloge("buffer size is invalid\n");
422         return TEE_ERROR_GENERIC;
423     }
424     operation->params[i].memref.size   = (uint32_t)params[i].memref.size;
425     buf[i]                             = alloc_sharemem(params[i].memref.size);
426     operation->params[i].memref.buffer = (uint32_t)((uintptr_t)buf[i] & COREAPI_ADDR_MASK);
427 
428     /* change for codex CONSTANT_EXPRESSION_RESULT */
429 #ifdef __aarch64__
430     operation->p_h_addr[i] = (uint32_t)(((uintptr_t)buf[i]) >> MOVE_OFFSET);
431 #else
432     operation->p_h_addr[i] = 0;
433 #endif
434 
435     if (buf[i] == NULL) {
436         tloge("alloc params[%u] membuff fail, size = %zu\n", i, params[i].memref.size);
437         return TEE_ERROR_OUT_OF_MEMORY;
438     }
439     if (memcpy_s(buf[i], params[i].memref.size, params[i].memref.buffer, params[i].memref.size) != EOK)
440         return TEE_ERROR_GENERIC;
441 
442     return TEE_SUCCESS;
443 }
444 
handle_malloc_fail(uint32_t types,int8_t ** buf,uint32_t buf_num,const TEE_Param * params)445 static void handle_malloc_fail(uint32_t types, int8_t **buf, uint32_t buf_num, const TEE_Param *params)
446 {
447     uint32_t i;
448     uint32_t param_type;
449 
450     for (i = 0; i < buf_num; i++) {
451         param_type = TEE_PARAM_TYPE_GET(types, i);
452         switch (param_type) {
453         case TEE_PARAM_TYPE_NONE:
454         case TEE_PARAM_TYPE_VALUE_INPUT:
455         case TEE_PARAM_TYPE_VALUE_OUTPUT:
456         case TEE_PARAM_TYPE_VALUE_INOUT:
457             break;
458         case TEE_PARAM_TYPE_MEMREF_INPUT:
459         case TEE_PARAM_TYPE_MEMREF_OUTPUT:
460         case TEE_PARAM_TYPE_MEMREF_INOUT:
461             if (buf[i] != NULL) {
462                 common_free_sharemem(buf[i], params[i].memref.size);
463                 buf[i] = NULL;
464             }
465             break;
466         default:
467             tloge("invalid param[%u] type %u\n", i, param_type);
468             break;
469         }
470     }
471 }
472 
push_params_in_shareregion(uint32_t types,const TEE_Param * params,struct smc_operation * operation)473 static TEE_Result push_params_in_shareregion(uint32_t types, const TEE_Param *params, struct smc_operation *operation)
474 {
475     uint32_t i;
476     uint32_t param_type;
477     void *buf[TEE_PARAM_NUM] = {0};
478 
479     TEE_Result ret = push_params_check(params, operation);
480     if (ret != TEE_SUCCESS)
481         return ret;
482 
483     if (memset_s(operation, sizeof(*operation), 0x0, sizeof(*operation)) != EOK)
484         return TEE_ERROR_GENERIC;
485 
486     operation->types = types;
487     for (i = 0; i < TEE_PARAM_NUM; i++) {
488         param_type = TEE_PARAM_TYPE_GET(types, i);
489         switch (param_type) {
490         case TEE_PARAM_TYPE_NONE:
491             break;
492         case TEE_PARAM_TYPE_VALUE_INPUT:
493         case TEE_PARAM_TYPE_VALUE_OUTPUT:
494         case TEE_PARAM_TYPE_VALUE_INOUT:
495             operation->params[i].value.a = params[i].value.a;
496             operation->params[i].value.b = params[i].value.b;
497             break;
498         case TEE_PARAM_TYPE_MEMREF_INPUT:
499         case TEE_PARAM_TYPE_MEMREF_OUTPUT:
500         case TEE_PARAM_TYPE_MEMREF_INOUT:
501             ret = handle_mem_buffer(i, params, operation, (int8_t **)buf);
502             if (ret != TEE_SUCCESS)
503                 goto malloc_fail;
504             break;
505         default:
506             tloge("invalid param[%u] type %u\n", i, param_type);
507             ret = TEE_ERROR_BAD_PARAMETERS;
508             goto malloc_fail;
509         }
510     }
511 
512     return TEE_SUCCESS;
513 
514 malloc_fail:
515     handle_malloc_fail(types, (int8_t **)buf, TEE_PARAM_NUM, params);
516     return ret;
517 }
518 
param_check(const TEE_Param * params,const struct smc_operation * orig_operation,const struct smc_operation * operation)519 static TEE_Result param_check(const TEE_Param *params, const struct smc_operation *orig_operation,
520                               const struct smc_operation *operation)
521 {
522     if (params == NULL || orig_operation == NULL || operation == NULL) {
523         tloge("param invalid\n");
524         return TEE_ERROR_BAD_PARAMETERS;
525     }
526 
527     return TEE_SUCCESS;
528 }
529 
clean_buf_addr(struct smc_operation * orig_operation,struct smc_operation * operation,uint32_t i)530 static void clean_buf_addr(struct smc_operation *orig_operation, struct smc_operation *operation, uint32_t i)
531 {
532     operation->p_h_addr[i]                  = 0;
533     operation->params[i].memref.buffer      = 0;
534     orig_operation->p_h_addr[i]             = 0;
535     orig_operation->params[i].memref.buffer = 0;
536 }
537 
pop_params_from_shareregion(uint32_t types,TEE_Param * params,struct smc_operation * orig_operation,struct smc_operation * operation,bool copy)538 static TEE_Result pop_params_from_shareregion(uint32_t types, TEE_Param *params, struct smc_operation *orig_operation,
539                                               struct smc_operation *operation, bool copy)
540 {
541     uint32_t param_type;
542 
543     TEE_Result ret = param_check(params, orig_operation, operation);
544     if (ret != TEE_SUCCESS)
545         return ret;
546 
547     for (uint32_t i = 0; i < TEE_PARAM_NUM; i++) {
548         param_type = TEE_PARAM_TYPE_GET(types, i);
549         switch (param_type) {
550         case TEE_PARAM_TYPE_NONE:
551             break;
552         case TEE_PARAM_TYPE_VALUE_INPUT:
553         case TEE_PARAM_TYPE_VALUE_OUTPUT:
554         case TEE_PARAM_TYPE_VALUE_INOUT:
555             if (copy) {
556                 params[i].value.a = operation->params[i].value.a;
557                 params[i].value.b = operation->params[i].value.b;
558             }
559             break;
560         case TEE_PARAM_TYPE_MEMREF_INPUT:
561         case TEE_PARAM_TYPE_MEMREF_OUTPUT:
562         case TEE_PARAM_TYPE_MEMREF_INOUT:
563             tlogd("params buffer %x!\n", orig_operation->params[i].memref.buffer);
564             void *orig_buf = (void *)(uintptr_t)orig_operation->params[i].memref.buffer;
565             unsigned int orig_size = orig_operation->params[i].memref.size;
566             if (orig_operation->p_h_addr[i] != 0) {
567                 uint64_t tmp_addr = (((uint64_t)orig_operation->p_h_addr[i]) << MOVE_OFFSET) | (uintptr_t)orig_buf;
568                 orig_buf          = (void *)(uintptr_t)tmp_addr;
569             }
570 
571             if (orig_buf == NULL)
572                 continue;
573 
574             if (copy && memcpy_s(params[i].memref.buffer, orig_size, orig_buf, orig_size) != EOK)
575                 ret = TEE_ERROR_GENERIC;
576 
577             params[i].memref.size = operation->params[i].memref.size;
578 
579             if (copy && memset_s(orig_buf, orig_size, 0, orig_size) != EOK)
580                 ret = TEE_ERROR_GENERIC;
581 
582             common_free_sharemem(orig_buf, orig_size);
583             clean_buf_addr(orig_operation, operation, i); /* orig_buf leaves its scope, no need to set to NULL */
584             break;
585         default:
586             ret = TEE_ERROR_BAD_PARAMETERS;
587             break;
588         }
589     }
590 
591     return ret;
592 }
593 
ta2ta_pseudo_free_sharedmem(uint8_t * op,smc_cmd_t * smc_cmd,struct ret_vaild_handle * ret_handle,const struct ta2ta_ret_msg * ret_msg)594 static void ta2ta_pseudo_free_sharedmem(uint8_t *op, smc_cmd_t *smc_cmd, struct ret_vaild_handle *ret_handle,
595                                         const struct ta2ta_ret_msg *ret_msg)
596 {
597     if (op != NULL) {
598         TEE_Free(op);
599         op = NULL;
600     }
601 
602     if (ret_msg->ret == TEE_ERROR_SERVICE_NOT_EXIST)
603         ret_handle->ret = TEE_ERROR_ITEM_NOT_FOUND;
604 
605     /* smc cmd points to the beggining of the shared memory area */
606     if (memset_s(smc_cmd, PAGE_SIZE, 0, PAGE_SIZE) != EOK) {
607         if (ret_handle->ret == TEE_SUCCESS)
608             ret_handle->ret = TEE_ERROR_GENERIC;
609     }
610 
611     common_free_sharemem((int8_t *)smc_cmd, PAGE_SIZE);
612     smc_cmd = NULL;
613 
614     if (ret_handle->valid_handle != UINT32_MAX)
615         delete_ta2ta_session_id(ret_handle->valid_handle);
616 }
617 
release_mem_in_params(uint32_t types,struct smc_operation * orig_operation,struct smc_operation * operation)618 static void release_mem_in_params(uint32_t types, struct smc_operation *orig_operation,
619                                   struct smc_operation *operation)
620 {
621     uint32_t i;
622     uint32_t param_type;
623     uint64_t tmp_addr;
624 
625     /* type is 0 means no need to handle */
626     if (types == 0)
627         return;
628 
629     if (orig_operation == NULL || operation == NULL)
630         return;
631 
632     for (i = 0; i < TEE_PARAM_NUM; i++) {
633         param_type = TEE_PARAM_TYPE_GET(types, i);
634         switch (param_type) {
635         case TEE_PARAM_TYPE_MEMREF_INPUT:
636         case TEE_PARAM_TYPE_MEMREF_OUTPUT:
637         case TEE_PARAM_TYPE_MEMREF_INOUT:
638             tmp_addr = ((((uint64_t)orig_operation->p_h_addr[i]) << MOVE_OFFSET) |
639                         ((uint64_t)orig_operation->params[i].memref.buffer));
640             common_free_sharemem((int8_t *)(uintptr_t)tmp_addr, orig_operation->params[i].memref.size);
641             clean_buf_addr(orig_operation, operation, i);
642             tmp_addr = 0;
643             break;
644         default:
645             break;
646         }
647     }
648 }
649 
650 /*
651  * Notice:
652  * TA2TA call will alloc a copy of TA's params in all TA sharemem region,
653  * It may be cause some secure problem.
654  */
655 #define TA2TA_OPEN_SESSION   0x1
656 #define TA2TA_INVOKE_COMMAND 0x2
657 #define TA2TA_CLOSE_SESSION  0x3
658 
ta2ta_pseudo_init_smc_cmd(const struct ta2ta_smc_call_params * smc_call_params,struct ta2ta_msg * call_msg,TEE_TASessionHandle * valid_handle,smc_cmd_t * smc_cmd)659 static TEE_Result ta2ta_pseudo_init_smc_cmd(const struct ta2ta_smc_call_params *smc_call_params,
660                                             struct ta2ta_msg *call_msg, TEE_TASessionHandle *valid_handle,
661                                             smc_cmd_t *smc_cmd)
662 {
663     switch (smc_call_params->call_type) {
664     case TA2TA_OPEN_SESSION:
665         smc_cmd->cmd_type = CMD_TYPE_GLOBAL;
666         smc_cmd->context    = 0;
667         smc_cmd->cmd_id     = GLOBAL_CMD_ID_OPEN_SESSION;
668         if (new_ta2ta_session_handle(valid_handle) != TEE_SUCCESS) {
669             tloge("get valid handle failed\n");
670             return TEE_ERROR_GENERIC;
671         }
672         call_msg->handle = *valid_handle;
673         break;
674     case TA2TA_INVOKE_COMMAND:
675         smc_cmd->cmd_type = CMD_TYPE_TA;
676         smc_cmd->context    = smc_call_params->session_id;
677         smc_cmd->cmd_id     = smc_call_params->command_id;
678         break;
679     case TA2TA_CLOSE_SESSION:
680         smc_cmd->cmd_type = CMD_TYPE_GLOBAL;
681         smc_cmd->context    = smc_call_params->session_id;
682         smc_cmd->cmd_id     = GLOBAL_CMD_ID_CLOSE_SESSION;
683         break;
684     default:
685         /* should not get here */
686         tloge("invalid call type %u\n", smc_call_params->call_type);
687         return TEE_ERROR_GENERIC;
688     }
689 
690     return TEE_SUCCESS;
691 }
692 
ta2ta_pseudo_alloc_sharedmem(const TEE_UUID * uuid,smc_cmd_t ** smc_cmd,uint8_t ** shared_mem)693 static TEE_Result ta2ta_pseudo_alloc_sharedmem(const TEE_UUID *uuid, smc_cmd_t **smc_cmd, uint8_t **shared_mem)
694 {
695     if (uuid == NULL)
696         return TEE_ERROR_BAD_PARAMETERS;
697 
698     /*
699      * Allocate shared memory buffer for all the information that is needed,
700      * We need to allocate it all at once because the operation allocates page aligned buffers
701      * and the fractions are very small which would lead to waste of shared memory
702      */
703     *shared_mem = alloc_sharemem(PAGE_SIZE);
704     if (*shared_mem == NULL) {
705         tloge("alloc smc cmd fail\n");
706         return TEE_ERROR_OUT_OF_MEMORY;
707     }
708     if (memset_s(*shared_mem, PAGE_SIZE, 0, PAGE_SIZE) != EOK) {
709         common_free_sharemem((int8_t *)(*shared_mem), PAGE_SIZE);
710         *shared_mem = NULL;
711         return TEE_ERROR_GENERIC;
712     }
713 
714     /* construct new smc cmd */
715     *smc_cmd = (smc_cmd_t *)(*shared_mem);
716     *shared_mem += sizeof(**smc_cmd);
717 
718     if (memcpy_s((*smc_cmd)->uuid, sizeof((*smc_cmd)->uuid), uuid, sizeof(*uuid)) != EOK) {
719         common_free_sharemem((int8_t *)(*smc_cmd), sizeof(**smc_cmd));
720         *smc_cmd = NULL;
721         return TEE_ERROR_GENERIC;
722     }
723     return TEE_SUCCESS;
724 }
725 
ta2ta_pseudo_handle_msg(const struct ta2ta_smc_call_params * smc_call_params,const smc_cmd_t * smc_cmd,struct ta2ta_msg * call_msg,struct ta2ta_ret_msg * ret_msg)726 static TEE_Result ta2ta_pseudo_handle_msg(const struct ta2ta_smc_call_params *smc_call_params,
727                                           const smc_cmd_t *smc_cmd, struct ta2ta_msg *call_msg,
728                                           struct ta2ta_ret_msg *ret_msg)
729 {
730     uint32_t ret;
731 
732     call_msg->cmd = (uintptr_t)smc_cmd;
733     if (ipc_msg_snd(TA2TA_CALL, get_global_handle(), call_msg, sizeof(*call_msg)) != SRE_OK) {
734         tloge("message send failed\n");
735         return TEE_ERROR_GENERIC;
736     }
737     ret = ipc_msg_rcv_safe(OS_WAIT_FOREVER, NULL, ret_msg, sizeof(*ret_msg), get_global_handle());
738     if (ret != SRE_OK) {
739         tloge("receive msg fail in ta2ta call, ret=0x%x\n", ret);
740         return TEE_ERROR_GENERIC;
741     }
742 
743     (void)smc_call_params;
744     return TEE_SUCCESS;
745 }
746 
ta2ta_pseudo_handle_ret(struct ta2ta_smc_call_params * smc_call_params,struct ta2ta_ret_msg * ret_msg,uint8_t * op,struct smc_operation * operation,TEE_TASessionHandle * valid_handle)747 static TEE_Result ta2ta_pseudo_handle_ret(struct ta2ta_smc_call_params *smc_call_params, struct ta2ta_ret_msg *ret_msg,
748                                           uint8_t *op, struct smc_operation *operation,
749                                           TEE_TASessionHandle *valid_handle)
750 {
751     TEE_Result ret   = ret_msg->ret;
752     smc_cmd_t *t_cmd = &(ret_msg->cmd);
753 
754     if (smc_call_params->param_types) {
755         /*
756          * operation was part of the shared memory and might be corrupted so use the saved
757          * copy for buffer addresses
758          */
759         if (pop_params_from_shareregion(smc_call_params->param_types, smc_call_params->params,
760                                         (struct smc_operation *)op, operation,
761                                         ret_msg->ret == TEE_SUCCESS) != TEE_SUCCESS)
762             tloge("pop params from share region failed\n");
763     }
764 
765     if (ret_msg->ret == TEE_SUCCESS) {
766         /* in TA2TA_OPEN_SESSION, handle cannot be NULL */
767         if ((smc_call_params->call_type == TA2TA_OPEN_SESSION) && (smc_call_params->handle != NULL)) {
768             tlogd("ta2ta session id = 0x%x\n", t_cmd->context);
769             ret = set_ta2ta_session_handle(smc_call_params->uuid, t_cmd->context, *valid_handle);
770             if (ret == TEE_SUCCESS) {
771                 *(smc_call_params->handle) = *valid_handle;
772                 *valid_handle              = UINT32_MAX; /* not delete session handle */
773             }
774         }
775     }
776     return ret;
777 }
778 
ta2ta_pseudo_smc_call(struct ta2ta_smc_call_params * smc_call_params)779 static TEE_Result ta2ta_pseudo_smc_call(struct ta2ta_smc_call_params *smc_call_params)
780 {
781     smc_cmd_t *smc_cmd                 = NULL;
782     struct smc_operation *operation    = NULL;
783     struct ta2ta_msg call_msg          = {0};
784     struct ta2ta_ret_msg ret_msg       = {0};
785     struct ret_vaild_handle ret_handle = {TEE_ERROR_GENERIC, UINT32_MAX};
786     uint8_t *shared_mem                = NULL;
787     uint8_t *op                        = NULL;
788 
789     ret_handle.ret = ta2ta_pseudo_alloc_sharedmem(smc_call_params->uuid, &smc_cmd, &shared_mem);
790     if (ret_handle.ret != TEE_SUCCESS)
791         return ret_handle.ret;
792 
793     ret_handle.ret = TEE_ERROR_GENERIC;
794 
795     if (ta2ta_pseudo_init_smc_cmd(smc_call_params, &call_msg, &ret_handle.valid_handle, smc_cmd) != TEE_SUCCESS)
796         goto free_shardmem;
797 
798     if (smc_call_params->param_types) {
799         /* operation has to be 4 byte aligned */
800         operation = (struct smc_operation *)(((uintptr_t)shared_mem + MEMORY_OFFSET) & (~MEMORY_MASK));
801         op        = TEE_Malloc(sizeof(*operation), 0);
802         if (op == NULL)
803             goto free_shardmem;
804 
805         ret_handle.ret = push_params_in_shareregion(smc_call_params->param_types, smc_call_params->params,
806                                                     (struct smc_operation *)op);
807         if (ret_handle.ret != TEE_SUCCESS)
808             goto free_shardmem;
809 
810         if (memcpy_s(operation, PAGE_SIZE - ((uintptr_t)(operation) - (uintptr_t)(smc_cmd)), op,
811             sizeof(*operation)) != EOK) {
812             ret_handle.ret = TEE_ERROR_GENERIC;
813             goto release_param_mem;
814         }
815 
816         smc_cmd->operation_phys = (uint32_t)((uintptr_t)operation & COREAPI_ADDR_MASK);
817 #ifdef __aarch64__
818         smc_cmd->operation_h_phys = (uint32_t)(((uintptr_t)operation) >> MOVE_OFFSET);
819 #else
820         smc_cmd->operation_h_phys = 0;
821 #endif
822     } else {
823         smc_cmd->operation_phys   = 0;
824         smc_cmd->operation_h_phys = 0;
825     }
826     /* Not set:dev_file_id, agent_id, login_method, login_data, err_origin */
827     ret_handle.ret = ta2ta_pseudo_handle_msg(smc_call_params, smc_cmd, &call_msg, &ret_msg);
828     if (ret_handle.ret != TEE_SUCCESS)
829         goto release_param_mem;
830 
831     ret_handle.ret = ta2ta_pseudo_handle_ret(smc_call_params, &ret_msg, op, operation, &ret_handle.valid_handle);
832     goto free_shardmem;
833 
834 release_param_mem:
835     release_mem_in_params(smc_call_params->param_types, (struct smc_operation *)op, operation);
836 free_shardmem:
837     ta2ta_pseudo_free_sharedmem(op, smc_cmd, &ret_handle, &ret_msg);
838     return ret_handle.ret;
839 }
840 
TEE_OpenTASession(const TEE_UUID * destination,uint32_t cancellationRequestTimeout,uint32_t paramTypes,TEE_Param params[TEE_PARAM_NUM],TEE_TASessionHandle * session,uint32_t * returnOrigin)841 TEE_Result TEE_OpenTASession(const TEE_UUID *destination, uint32_t cancellationRequestTimeout, uint32_t paramTypes,
842                              TEE_Param params[TEE_PARAM_NUM], TEE_TASessionHandle *session, uint32_t *returnOrigin)
843 {
844     TEE_Result ret;
845 
846     if ((destination == NULL) || (session == NULL))
847         return TEE_ERROR_BAD_PARAMETERS;
848 
849     PARAM_NOT_USED(cancellationRequestTimeout);
850 
851     if (returnOrigin != NULL)
852         *returnOrigin = TEE_ORIGIN_TEE;
853 
854     struct ta2ta_smc_call_params smc_call_params = {0};
855     smc_call_params.call_type                    = TA2TA_OPEN_SESSION;
856     smc_call_params.uuid                         = destination;
857     smc_call_params.param_types                  = paramTypes;
858     smc_call_params.params                       = params;
859     smc_call_params.handle                       = session;
860     ret                                          = ta2ta_pseudo_smc_call(&smc_call_params);
861 
862     return ret;
863 }
864 
TEE_CloseTASession(TEE_TASessionHandle session)865 void TEE_CloseTASession(TEE_TASessionHandle session)
866 {
867     struct ta2ta_session_handle *session_handle = NULL;
868     TEE_Result ret;
869     int32_t pthread_ret;
870 
871     if (get_ta2ta_session_handle(session, &session_handle) != TEE_SUCCESS) {
872         tloge("ta2ta session id is not exist\n");
873         return;
874     }
875 
876     struct ta2ta_smc_call_params smc_call_params = {0};
877     smc_call_params.call_type                    = TA2TA_CLOSE_SESSION;
878     smc_call_params.uuid                         = &session_handle->uuid;
879     smc_call_params.session_id                   = session_handle->session_id;
880     smc_call_params.handle                       = NULL;
881 
882     ret = ta2ta_pseudo_smc_call(&smc_call_params);
883     if (ret != TEE_SUCCESS) {
884         tloge("ta2ta close sesion failed ret:0x%x\n", ret);
885         return;
886     }
887 
888     pthread_ret = mutex_lock_ops(&g_global_mutex);
889     if (pthread_ret != MUTEX_SUCC_RET) {
890         tloge("mutex lock failed with ret %d\n", pthread_ret);
891         return;
892     }
893 
894     clear_bitmap(g_handle_bitmap, HANDLE_MAX, session_handle->handle);
895     dlist_delete(&session_handle->list);
896 
897     pthread_ret = pthread_mutex_unlock(&g_global_mutex);
898     if (pthread_ret != MUTEX_SUCC_RET)
899         tloge("mutex unlock failed with ret %d\n", pthread_ret);
900 
901     TEE_Free(session_handle);
902 }
903 
TEE_InvokeTACommand(TEE_TASessionHandle session,uint32_t cancellationRequestTimeout,uint32_t commandID,uint32_t paramTypes,TEE_Param params[TEE_PARAM_NUM],uint32_t * returnOrigin)904 TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, uint32_t cancellationRequestTimeout, uint32_t commandID,
905                                uint32_t paramTypes, TEE_Param params[TEE_PARAM_NUM], uint32_t *returnOrigin)
906 {
907     TEE_Result ret;
908     PARAM_NOT_USED(cancellationRequestTimeout);
909 
910     struct ta2ta_session_handle *session_handle = NULL;
911 
912     if (returnOrigin != NULL)
913         *returnOrigin = TEE_ORIGIN_TEE;
914 
915     if (get_ta2ta_session_handle(session, &session_handle) != TEE_SUCCESS) {
916         tloge("ta2ta session_handle is not exist\n");
917         return TEE_ERROR_ITEM_NOT_FOUND;
918     }
919 
920     struct ta2ta_smc_call_params smc_call_params = {0};
921     smc_call_params.call_type                    = TA2TA_INVOKE_COMMAND;
922     smc_call_params.uuid                         = &session_handle->uuid;
923     smc_call_params.session_id                   = session_handle->session_id;
924     smc_call_params.command_id                   = commandID;
925     smc_call_params.param_types                  = paramTypes;
926     smc_call_params.params                       = params;
927     smc_call_params.handle                       = NULL;
928     ret                                          = ta2ta_pseudo_smc_call(&smc_call_params);
929 
930     return ret;
931 }
932 
TEE_GetCancellationFlag(void)933 bool TEE_GetCancellationFlag(void)
934 {
935     return false; /* not suport */
936 }
937 
TEE_UnmaskCancellation(void)938 bool TEE_UnmaskCancellation(void)
939 {
940     return false; /* not suport */
941 }
942 
TEE_MaskCancellation(void)943 bool TEE_MaskCancellation(void)
944 {
945     return false; /* not suport */
946 }
947 
delete_all_ta2ta_session(uint32_t tid)948 void delete_all_ta2ta_session(uint32_t tid)
949 {
950     struct ta2ta_session_handle *handle_entry = NULL;
951     struct ta2ta_session_handle *tmp_entry = NULL;
952 
953     int32_t ret = mutex_lock_ops(&g_global_mutex);
954     if (ret != MUTEX_SUCC_RET) {
955         tloge("mutex lock failed with ret %d\n", ret);
956         return;
957     }
958 
959     dlist_for_each_entry_safe(handle_entry, tmp_entry, &g_handle_head, struct ta2ta_session_handle, list) {
960         if (handle_entry->src_tid == tid) {
961             clear_bitmap(g_handle_bitmap, HANDLE_MAX, handle_entry->handle);
962             dlist_delete(&handle_entry->list);
963             TEE_Free(handle_entry);
964             handle_entry = NULL;
965         }
966     }
967 
968     ret = pthread_mutex_unlock(&g_global_mutex);
969     if (ret != MUTEX_SUCC_RET)
970         tloge("mutex unlock failed with ret %d\n", ret);
971 }
972 
clear_session_exception(uint32_t session_id)973 void clear_session_exception(uint32_t session_id)
974 {
975     delete_tls_info(session_id);
976     del_session_cancel_state(session_id);
977 }
978 
get_current_uuid(void)979 __attribute__((weak)) TEE_UUID *get_current_uuid(void)
980 {
981     return get_running_uuid();
982 }
983 
get_current_session_id(void)984 uint32_t get_current_session_id(void)
985 {
986     struct running_info *info = get_tls_running_info();
987 
988     return (info != NULL) ? info->session_id : 0U;
989 }
990