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(>ask_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