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 #include "tee_app_load_srv.h"
13 #include <limits.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <openssl/obj_mac.h>
17 #include <mem_ops.h>
18 #include <fileio.h>
19 #include <sys/mman.h>
20 #include <dyn_conf_dispatch_inf.h>
21 #include <spawn_ext.h>
22 #include "tee_mem_mgmt_api.h"
23 #include "gtask_inner.h"
24 #include "mem_manager.h"
25 #include "service_manager.h"
26 #include "session_manager.h"
27 #include "tee_log.h"
28 #include "securec.h"
29 #include "tee_crypto_api.h"
30 #include "permsrv_api.h"
31 #include "dynload.h"
32 #include "tee_load_lib.h"
33
34 #include "drvcall_dyn_conf_builder.h"
35 #include "drv_dyn_conf_builder.h"
36 #include "target_type.h"
37 #include "tee_elf_verify.h"
38 #include "global_task.h"
39 #include "task_dynamic_adaptor.h"
40 #include "load_app_comm.h"
41 #include <sys/mman.h>
42
43 typedef struct {
44 smc_cmd_t smc_cmd;
45 bool elf_loading; /* this flag is only for perm service crash callback */
46 } elf_load_context_t;
47
48 static elf_load_context_t g_load_context;
49
rename_tmp_file(const char * new_name,uint32_t len)50 TEE_Result rename_tmp_file(const char *new_name, uint32_t len)
51 {
52 elf_image_info *img_info_ptr = get_img_info_ptr();
53 if (img_info_ptr == NULL) {
54 tloge("the ptr is null\n");
55 return TEE_ERROR_GENERIC;
56 }
57 if (len == 0 || len > MAX_TAFS_NAME_LEN || new_name == NULL) {
58 tloge("new file name error\n");
59 return TEE_ERROR_BAD_PARAMETERS;
60 }
61
62 if (vfs_rename(img_info_ptr->img_fp, new_name) < 0) {
63 tloge("rename tmp file name failed\n");
64 return TEE_ERROR_GENERIC;
65 }
66
67 for (uint32_t idx = 0; idx < len; idx++)
68 img_info_ptr->tmp_file_name[idx] = new_name[idx];
69 img_info_ptr->tmp_file_name[len - 1] = '\0';
70
71 return TEE_SUCCESS;
72 }
73
unlink_file(void)74 static void unlink_file(void)
75 {
76 elf_image_info *img_info_ptr = get_img_info_ptr();
77 if (img_info_ptr == NULL) {
78 tloge("the ptr is null\n");
79 return;
80 }
81 if (img_info_ptr->tmp_file_exist == false)
82 return;
83
84 if (unlink(img_info_ptr->tmp_file_name) != TEE_SUCCESS)
85 tloge("file unlink failed\n");
86 else
87 img_info_ptr->tmp_file_exist = false;
88 }
89
close_tmp_file(void)90 static TEE_Result close_tmp_file(void)
91 {
92 elf_image_info *img_info_ptr = get_img_info_ptr();
93 if (img_info_ptr == NULL) {
94 tloge("the ptr is null\n");
95 return TEE_ERROR_GENERIC;
96 }
97 if (img_info_ptr->img_fp < 0)
98 return TEE_SUCCESS;
99
100 if (close(img_info_ptr->img_fp) != 0) {
101 tloge("tmp fileclose failed\n");
102 return TEE_ERROR_GENERIC;
103 }
104 img_info_ptr->img_fp = -1;
105
106 return TEE_SUCCESS;
107 }
108
do_remove_file(void)109 static void do_remove_file(void)
110 {
111 if (close_tmp_file() != TEE_SUCCESS)
112 tloge("close tmp file failed\n");
113 unlink_file();
114 }
115
free_img_load_buf(void)116 void free_img_load_buf(void)
117 {
118 elf_image_info *img_info_ptr = get_img_info_ptr();
119 if (img_info_ptr->img_buf == NULL)
120 return;
121
122 /* do NOT free, map from tafs */
123 (void)munmap((void *)(uintptr_t)img_info_ptr->img_buf, img_info_ptr->aligned_img_size);
124 img_info_ptr->img_buf = NULL;
125
126 do_remove_file();
127
128 (void)memset_s(img_info_ptr, sizeof(*img_info_ptr), 0, sizeof(*img_info_ptr));
129 img_info_ptr->img_fp = -1;
130
131 (void)memset_s(&g_load_context, sizeof(g_load_context), 0, sizeof(g_load_context));
132 }
133
need_load_app(const smc_cmd_t * cmd)134 TEE_Result need_load_app(const smc_cmd_t *cmd)
135 {
136 TEE_UUID srv_uuid;
137 uint32_t param_type = 0;
138 TEE_Param *params = NULL;
139 int32_t need_load;
140
141 if (cmd == NULL)
142 return TEE_ERROR_BAD_PARAMETERS;
143 /* get uuid */
144 TEE_Result ret = cmd_global_ns_get_params(cmd, ¶m_type, ¶ms);
145 if (ret != TEE_SUCCESS)
146 return TEE_ERROR_BAD_PARAMETERS;
147 if (params == NULL)
148 return TEE_ERROR_BAD_PARAMETERS;
149 if (TEE_PARAM_TYPE_GET(param_type, 0) != TEE_PARAM_TYPE_MEMREF_INOUT)
150 return TEE_ERROR_BAD_PARAMETERS;
151 if (params->memref.size < sizeof(TEE_UUID))
152 return TEE_ERROR_BAD_PARAMETERS;
153 /* get uuid */
154 errno_t eret = memcpy_s(&srv_uuid, sizeof(TEE_UUID), params->memref.buffer, sizeof(TEE_UUID));
155 if (eret != EOK)
156 return TEE_ERROR_SECURITY;
157
158 if (need_load_srv(&srv_uuid) == false) {
159 tlogd("no need load app\n");
160 need_load = 0;
161 } else {
162 tlogd("need load app\n");
163 need_load = 1;
164 }
165
166 *(int32_t *)(params->memref.buffer) = need_load;
167
168 if (need_load != 0)
169 tlogd("need_load flag is %x ==================\n", need_load);
170
171 return TEE_SUCCESS;
172 }
173
tee_cmd_params_parse(const smc_cmd_t * cmd,TEE_Param ** params)174 static TEE_Result tee_cmd_params_parse(const smc_cmd_t *cmd, TEE_Param **params)
175 {
176 TEE_Result tee_ret;
177 uint32_t param_type = 0;
178
179 /* get params for cmd, and check the param_type */
180 tee_ret = cmd_global_ns_get_params(cmd, ¶m_type, params);
181 if (tee_ret != TEE_SUCCESS) {
182 tloge("Failed to map cmd operation");
183 return TEE_ERROR_GENERIC;
184 }
185 bool check = (TEE_PARAM_TYPE_GET(param_type, 0) != TEE_PARAM_TYPE_MEMREF_INPUT ||
186 TEE_PARAM_TYPE_GET(param_type, 1) != TEE_PARAM_TYPE_VALUE_INOUT ||
187 TEE_PARAM_TYPE_GET(param_type, OUTPUT_MEM_REF_INDEX) != TEE_PARAM_TYPE_MEMREF_OUTPUT ||
188 TEE_PARAM_TYPE_GET(param_type, INPUT_VALUE_INDEX) != TEE_PARAM_TYPE_VALUE_INOUT);
189 if (check) {
190 tloge("Bad expected parameter types");
191 return TEE_ERROR_BAD_PARAMETERS;
192 }
193 if (*params == NULL ||
194 (*params)->memref.buffer == NULL ||
195 (*params)->memref.size <= sizeof(int32_t) ||
196 (*params)[OUTPUT_MEM_REF_INDEX].memref.size != sizeof(TEE_UUID))
197 return TEE_ERROR_GENERIC;
198
199 return TEE_SUCCESS;
200 }
201
tee_secure_img_get_version(const uint8_t * share_buf,uint32_t buff_size,uint32_t * img_version)202 static TEE_Result tee_secure_img_get_version(const uint8_t *share_buf, uint32_t buff_size, uint32_t *img_version)
203 {
204 bool check = (share_buf == NULL || img_version == NULL || buff_size < sizeof(teec_image_identity));
205 if (check)
206 return TEE_ERROR_BAD_PARAMETERS;
207 teec_image_identity img_identity = {0};
208 img_identity = *(teec_image_identity *)share_buf;
209
210 /* decide the TA version */
211 bool temp_check = (img_identity.magic_num1 == TA_HEAD_MAGIC1) && (img_identity.magic_num2 == TA_HEAD_MAGIC2) &&
212 (img_identity.version_num > 1);
213 if (temp_check) {
214 tlogd("new version ta, version num 0x%x\n", img_identity.version_num);
215 *img_version = img_identity.version_num;
216 } else {
217 /* Fisrt version of TA doesn't include magic number and version number */
218 tlogd("old version ta\n");
219 *img_version = TA_SIGN_VERSION;
220 }
221
222 return TEE_SUCCESS;
223 }
224
create_empty_file(elf_image_info * img_info_ptr)225 static TEE_Result create_empty_file(elf_image_info *img_info_ptr)
226 {
227 static uint32_t file_tmp_number = 0;
228 if (snprintf_s(img_info_ptr->tmp_file_name, MAX_TAFS_NAME_LEN, MAX_TAFS_NAME_LEN - 1, LOAD_TA_TMP_FILE,
229 TAFS_MOUNTPOINT, file_tmp_number) < 0) {
230 tloge("generate tmp file name failed\n");
231 return TEE_ERROR_BAD_PARAMETERS;
232 }
233 /* the value of file_tmp_number has no meaning, just change it to distinguish tmp file */
234 file_tmp_number++;
235 img_info_ptr->img_fp = open(img_info_ptr->tmp_file_name, O_CREAT | O_RDWR, RWRIGHT, (uint64_t)0);
236 if (img_info_ptr->img_fp < 0) {
237 tloge("file open failed: %d\n", img_info_ptr->img_fp);
238 return TEE_ERROR_BAD_PARAMETERS;
239 }
240 img_info_ptr->tmp_file_exist = true;
241 if (ftruncate(img_info_ptr->img_fp, img_info_ptr->aligned_img_size) != 0) {
242 tloge("file truncate failed\n");
243 do_remove_file();
244 return TEE_ERROR_BAD_PARAMETERS;
245 }
246
247 return TEE_SUCCESS;
248 }
249
get_img_load_buf(uint32_t size)250 static TEE_Result get_img_load_buf(uint32_t size)
251 {
252 if (size == 0 || size > PAGE_ALIGN_UP(size + ADDITIONAL_BUF_SIZE)) {
253 tloge("invalid img size %u\n", size);
254 return TEE_ERROR_BAD_PARAMETERS;
255 }
256
257 elf_image_info *img_info_ptr = get_img_info_ptr();
258 if (img_info_ptr == NULL) {
259 tloge("the ptr is null\n");
260 return TEE_ERROR_GENERIC;
261 }
262 img_info_ptr->aligned_img_size = PAGE_ALIGN_UP(size + ADDITIONAL_BUF_SIZE); /* get a redundance */
263
264 if (create_empty_file(img_info_ptr) != TEE_SUCCESS)
265 return TEE_ERROR_BAD_PARAMETERS;
266
267 void *map_addr_gtask = vfs_mmap(img_info_ptr->img_fp, img_info_ptr->aligned_img_size, 0);
268 if (map_addr_gtask == NULL) {
269 tloge("map file from tafs failed\n");
270 do_remove_file();
271 return TEE_ERROR_BAD_PARAMETERS;
272 }
273
274 img_info_ptr->img_size = size;
275 img_info_ptr->img_buf = map_addr_gtask;
276 img_info_ptr->img_offset = 0;
277 return TEE_SUCCESS;
278 }
279
handle_img_alloc_img_buff(uint32_t img_version,uint8_t * share_buf,uint32_t buf_len)280 static TEE_Result handle_img_alloc_img_buff(uint32_t img_version, uint8_t *share_buf, uint32_t buf_len)
281 {
282 TEE_Result ret;
283 uint32_t img_size = 0;
284
285 ret = tee_secure_get_img_size(img_version, share_buf, buf_len, &img_size);
286 if (ret != TEE_SUCCESS) {
287 tloge("get img size failed, ret=0x%x, img version=%u\n", ret, img_version);
288 return ret;
289 }
290
291 ret = get_img_load_buf(img_size);
292 if (ret != TEE_SUCCESS) {
293 tloge("Failed to get buf to load TA, img size %u\n", img_size);
294 return ret;
295 }
296 return TEE_SUCCESS;
297 }
298
tee_secure_image_recieve(uint8_t * share_buf,uint32_t buf_len)299 static TEE_Result tee_secure_image_recieve(uint8_t *share_buf, uint32_t buf_len)
300 {
301 uint32_t img_version = 0;
302 errno_t eret;
303
304 elf_image_info *img_info_ptr = get_img_info_ptr();
305 if (img_info_ptr == NULL) {
306 tloge("the ptr is null\n");
307 return TEE_ERROR_GENERIC;
308 }
309 /* The first time of TA image transfer, it may needs several time to complete */
310 if (img_info_ptr->img_buf == NULL) {
311 /* Get TA image version number */
312 TEE_Result ret = tee_secure_img_get_version(share_buf, buf_len, &img_version);
313 if (ret != TEE_SUCCESS)
314 return ret;
315 img_info_ptr->img_version = img_version;
316
317 ret = handle_img_alloc_img_buff(img_version, share_buf, buf_len);
318 if (ret != TEE_SUCCESS)
319 return ret;
320 }
321
322 /* Check the memcpy size */
323 if (img_info_ptr->img_offset > img_info_ptr->img_size ||
324 buf_len > (img_info_ptr->img_size - img_info_ptr->img_offset))
325 return TEE_ERROR_GENERIC;
326
327 eret = memcpy_s(img_info_ptr->img_buf + img_info_ptr->img_offset,
328 img_info_ptr->img_size - img_info_ptr->img_offset, share_buf, buf_len);
329 if (eret != EOK)
330 return TEE_ERROR_SECURITY;
331
332 img_info_ptr->img_offset += buf_len;
333 return TEE_SUCCESS;
334 }
335
recv_img_info_from_tzdriver(const smc_cmd_t * cmd,TEE_Param ** params)336 static TEE_Result recv_img_info_from_tzdriver(const smc_cmd_t *cmd, TEE_Param **params)
337 {
338 TEE_Result ret;
339 int32_t keep_loading;
340 uint8_t *share_buf = NULL;
341 uint32_t buf_len;
342
343 if (cmd == NULL || params == NULL)
344 return TEE_ERROR_BAD_PARAMETERS;
345
346 elf_image_info *img_info_ptr = get_img_info_ptr();
347 if (img_info_ptr == NULL) {
348 tloge("the ptr is null\n");
349 return TEE_ERROR_GENERIC;
350 }
351
352 /* Get params for cmd, and check the param_type */
353 ret = tee_cmd_params_parse(cmd, params);
354 if (ret != TEE_SUCCESS) {
355 tloge("Failed to parse cmd parameters\n");
356 return ret;
357 }
358 /* load elf start */
359 if ((*params)[INPUT_VALUE_INDEX].value.a == 0)
360 free_img_load_buf();
361
362 /* Get load flag for share buf, load_flag decide whether we need load again */
363 share_buf = (*params)->memref.buffer;
364 /* First byte of cmd share buffer indicates that if transfer need continue */
365 keep_loading = *(int32_t *)share_buf;
366 share_buf += sizeof(int32_t);
367 buf_len = (*params)->memref.size - sizeof(int32_t);
368
369 /* Receive secure image, it may be sent several times for length limit reason */
370 ret = tee_secure_image_recieve(share_buf, buf_len);
371 if (ret != TEE_SUCCESS) {
372 tloge("Failed to receive or parse ta image header: 0x%x\n", ret);
373 return ret;
374 }
375
376 if ((img_info_ptr->img_offset < img_info_ptr->img_size) && (keep_loading == 1))
377 /* Img send not finished yet, that's why we don't free g_img_info.img_buf here */
378 return RET_KEEP_LOADING;
379
380 return TEE_SUCCESS;
381 }
382
383 #ifdef CONFIG_DYNLIB_LOAD_SUPPORT
load_secure_lib(load_elf_func_params * param,const TEE_UUID * uuid,tee_img_type_t type)384 static TEE_Result load_secure_lib(load_elf_func_params *param, const TEE_UUID *uuid,
385 tee_img_type_t type)
386 {
387 struct service_struct *service = NULL;
388 char file_name[LIB_NAME_MAX] = {0};
389
390 param->fname = file_name;
391 param->fname_size = sizeof(file_name);
392
393 // 1. find service
394 // 2. add so to service,remember to remove lib when del service
395 // 3. for no xip,need to del lib when map lib
396 int32_t rc = find_service(uuid, 0, &service);
397 if (rc == -1 || service == NULL) {
398 tloge("service is not exist.uuid=%x\n", uuid->timeLow);
399 return TEE_ERROR_GENERIC;
400 }
401
402 rc = (int32_t)dynamic_load_lib_elf(param, service, uuid, 0, type);
403 if (rc == LOAD_FAIL) {
404 tloge("store lib elf fail\n");
405 return TEE_ERROR_GENERIC;
406 } else if (rc == LIB_EXIST) {
407 return TEE_SUCCESS;
408 }
409
410 TEE_Result ret = tee_add_libinfo(service, file_name, (size_t)sizeof(file_name), type);
411 if (ret != TEE_SUCCESS) {
412 // fail to link lib to service, need to release lib file
413 int result = unlink(file_name);
414 if (result != 0)
415 tloge("unlink %s failed\n", file_name);
416 return ret;
417 }
418 return TEE_SUCCESS;
419 }
420
load_secure_lib_image(tee_img_type_t type,const elf_verify_reply * verify_reply)421 static TEE_Result load_secure_lib_image(tee_img_type_t type, const elf_verify_reply *verify_reply)
422 {
423 TEE_Result ret;
424 load_elf_func_params param;
425 TEE_UUID uuid = {0};
426 TEE_UUID gtask_uuid = TEE_SERVICE_GLOBAL;
427 elf_image_info *img_info_ptr = get_img_info_ptr();
428
429 param.file_buffer = (char *)img_info_ptr->ptr_ta_elf;
430 param.file_size = verify_reply->payload_hdr.ta_elf_size;
431 param.lib_name = (char *)verify_reply->service_name;
432 uuid = verify_reply->srv_uuid;
433
434 /* dynamic_drv is in lib_list of gtask, heap_size of dynamic_drv should be large than it's file size */
435 if ((type == IMG_TYPE_DYNAMIC_DRV) || (type == IMG_TYPE_CRYPTO_DRV) ||
436 (type == IMG_TYPE_DYNAMIC_CLIENT)) {
437 if ((uint32_t)verify_reply->ta_property.heap_size < (uint32_t)param.file_size) {
438 tloge("error: dynamic_drv heap_size = %u < file_size = %u, file_name = %s\n",
439 (uint32_t)verify_reply->ta_property.heap_size, (uint32_t)param.file_size, param.lib_name);
440 return TEE_ERROR_BAD_PARAMETERS;
441 }
442 uuid = gtask_uuid;
443 }
444
445 ret = load_secure_lib(¶m, &uuid, type);
446 if (ret != TEE_SUCCESS) {
447 tloge("Failed to load library image, file_name = %s\n", param.lib_name);
448 return ret;
449 }
450 return TEE_SUCCESS;
451 }
452 #else
load_secure_lib_image(tee_img_type_t type,const elf_verify_reply * verify_reply)453 static TEE_Result load_secure_lib_image(tee_img_type_t type, const elf_verify_reply *verify_reply)
454 {
455 (void)type;
456 (void)verify_reply;
457 tloge("Unsupported dyn library load\n");
458 return TEE_ERROR_NOT_SUPPORTED;
459 }
460 #endif
461
462
tee_unregister_dyn_config(elf_verify_reply * verify_reply)463 static void tee_unregister_dyn_config(elf_verify_reply *verify_reply)
464 {
465 if (verify_reply->conf_registed)
466 tee_ext_notify_unload_ta(&verify_reply->srv_uuid);
467
468 /* if the drv or drvcall has registered dyn perm, we should unregister them */
469 if (verify_reply->dyn_conf_registed) {
470 if (verify_reply->mani_ext.target_type == DRV_TARGET_TYPE)
471 unregister_conf(uninstall_drv_permission, verify_reply->service_name,
472 verify_reply->service_name_len);
473 else if (verify_reply->mani_ext.target_type == TA_TARGET_TYPE ||
474 verify_reply->mani_ext.target_type == SRV_TARGET_TYPE ||
475 verify_reply->mani_ext.target_type == CLIENT_TARGET_TYPE)
476 unregister_conf(uninstall_drvcall_permission, &verify_reply->srv_uuid, sizeof(struct tee_uuid));
477 else
478 tloge("type %d is invalid, cannot unregister dyn config\n", verify_reply->mani_ext.target_type);
479
480 verify_reply->dyn_conf_registed = false;
481 }
482 }
483
load_secure_file_image_pre(const smc_cmd_t * cmd,TEE_Param ** params_back)484 static TEE_Result load_secure_file_image_pre(const smc_cmd_t *cmd, TEE_Param **params_back)
485 {
486 TEE_Param *params = NULL;
487
488 /* do age service & lib */
489 TEE_Result ret = age_service();
490 if (ret != TEE_SUCCESS)
491 return ret;
492
493 age_timeout_lib();
494
495 /* recv img & alloc img buf */
496 set_load_ta_mode_global_ptr();
497 ret = recv_img_info_from_tzdriver(cmd, ¶ms);
498 if (ret != TEE_SUCCESS)
499 return ret;
500
501 *params_back = params;
502 return TEE_SUCCESS;
503 }
504
check_verify_reply(TEE_Param * params,elf_verify_reply * verify_reply,tee_img_type_t * img_type)505 static TEE_Result check_verify_reply(TEE_Param *params,
506 elf_verify_reply *verify_reply, tee_img_type_t *img_type)
507 {
508 TEE_Result ret;
509
510 if (verify_reply->off_ta_elf == INVALID_OFFSET) {
511 tloge("empty ta elf buffer\n");
512 return TEE_ERROR_BAD_PARAMETERS;
513 }
514
515 elf_image_info *img_info_ptr = get_img_info_ptr();
516 /* check img permission */
517 ret = tee_secure_img_permission_check(img_info_ptr->img_version, verify_reply);
518 if (ret != TEE_SUCCESS) {
519 tloge("Failed to pass img permission check\n");
520 return ret;
521 }
522
523 /* check img type */
524 *img_type = tee_secure_get_img_type(verify_reply, img_info_ptr->img_version);
525
526 /*
527 * before load_dyn_drv, we need judge it's type from teecd , dynamic drv or crypto drv
528 * or dynamic client
529 */
530 if ((params != NULL) && params[1].value.a == LOAD_DYNAMIC_DRV && *img_type != IMG_TYPE_DYNAMIC_DRV &&
531 *img_type != IMG_TYPE_CRYPTO_DRV && *img_type != IMG_TYPE_DYNAMIC_CLIENT) {
532 tloge("load_dyn_drv only support dynamic_drv type, img_type = %d, file_name = %s\n",
533 *img_type, (char *)verify_reply->service_name);
534 return TEE_ERROR_BAD_PARAMETERS;
535 }
536
537 return ret;
538 }
539
img_unpack_copy_request_param(elf_verify_req * req_msg)540 static TEE_Result img_unpack_copy_request_param(elf_verify_req *req_msg)
541 {
542 elf_image_info *img_info_ptr = get_img_info_ptr();
543 req_msg->version = img_info_ptr->img_version;
544 if (strcpy_s(req_msg->tmp_file, sizeof(req_msg->tmp_file), img_info_ptr->tmp_file_name) != 0) {
545 tloge("copy file name failed\n");
546 return TEE_ERROR_BAD_PARAMETERS;
547 }
548 req_msg->img_size = img_info_ptr->img_size;
549
550 return TEE_SUCCESS;
551 }
552
img_unpack_copy_reply_msg(const elf_verify_reply * verify_reply)553 static void img_unpack_copy_reply_msg(const elf_verify_reply *verify_reply)
554 {
555 elf_image_info *img_info_ptr = get_img_info_ptr();
556 if (verify_reply->off_ta_elf == INVALID_OFFSET)
557 img_info_ptr->ptr_ta_elf = NULL;
558 else
559 img_info_ptr->ptr_ta_elf = img_info_ptr->img_buf + verify_reply->off_ta_elf;
560
561 if (verify_reply->off_manifest_buf == INVALID_OFFSET)
562 img_info_ptr->ptr_manifest_buf = NULL;
563 else
564 img_info_ptr->ptr_manifest_buf = img_info_ptr->img_buf + verify_reply->off_manifest_buf;
565 }
566
do_register_elf(const elf_verify_reply * reply,tee_img_type_t img_type)567 static TEE_Result do_register_elf(const elf_verify_reply *reply, tee_img_type_t img_type)
568 {
569 TEE_Result ret;
570 elf_image_info *img_info_ptr = get_img_info_ptr();
571
572 img_info_ptr->img_fp = open(img_info_ptr->tmp_file_name, O_RDWR, RWRIGHT, (uint64_t)0);
573 if (img_info_ptr->img_fp < 0) {
574 tloge("file reopen failed: %d\n", img_info_ptr->img_fp);
575 return TEE_ERROR_GENERIC;
576 }
577
578 img_unpack_copy_reply_msg(reply);
579 /* register img to tee */
580 if (img_type == IMG_TYPE_APP || img_type == IMG_TYPE_DYNAMIC_SRV) {
581 ret = load_secure_app_image(img_type, reply);
582 /*
583 * when load elf succ, we set tmp_file_exist to false to avoid unlink file when free_img_load_buf
584 * and elf will be unlink after open session succ
585 */
586 if (ret == TEE_SUCCESS)
587 img_info_ptr->tmp_file_exist = false;
588 } else {
589 ret = load_secure_lib_image(img_type, reply);
590 }
591 return ret;
592 }
593
process_register_elf(elf_verify_reply * reply,TEE_Param * params)594 static TEE_Result process_register_elf(elf_verify_reply *reply, TEE_Param *params)
595 {
596 TEE_Result ret;
597 tee_img_type_t img_type;
598
599 /* elf verify failed, need to release dyn config */
600 if (reply->verify_result != TEE_SUCCESS) {
601 tloge("receive elf verify fail result 0x%x\n", reply->verify_result);
602 ret = reply->verify_result;
603 goto release_dyn_conf;
604 }
605
606 ret = check_verify_reply(params, reply, &img_type);
607 if (ret != TEE_SUCCESS) {
608 tloge("check verify reply failed\n");
609 goto release_dyn_conf;
610 }
611
612 ret = do_register_elf(reply, img_type);
613 if (ret != TEE_SUCCESS) {
614 tloge("do register elf failed\n");
615 goto release_dyn_conf;
616 }
617
618 return TEE_SUCCESS;
619
620 /*
621 * if elf verify return success, means dyn config has been registered,
622 * so we should unregister dyn config when process verify reply failed
623 */
624 release_dyn_conf:
625 tee_unregister_dyn_config(reply);
626 return ret;
627 }
628
tee_secure_img_unpack_req(const elf_verify_req * req,const smc_cmd_t * cmd,TEE_Param * params,bool * async)629 static TEE_Result tee_secure_img_unpack_req(const elf_verify_req *req, const smc_cmd_t *cmd,
630 TEE_Param *params, bool *async)
631 {
632 TEE_Result ret;
633
634 #if defined(CONFIG_APP_TEE_PERM) || defined(CONFIG_APP_TEE_PERM_A32)
635 /* permservice will do elf verify */
636 (void)params;
637 if (cmd != NULL) {
638 /* backup smc cmd context here */
639 if (memcpy_s(&g_load_context.smc_cmd, sizeof(g_load_context.smc_cmd), cmd, sizeof(*cmd)) != EOK) {
640 tloge("backup smc cmd context failed\n");
641 ret = TEE_ERROR_GENERIC;
642 goto free_buf;
643 }
644 }
645 ret = tee_ext_elf_verify_req((void *)req, sizeof(*req));
646 if (ret != TEE_SUCCESS) {
647 tloge("tee ext elf verify failed\n");
648 goto free_buf;
649 }
650 g_load_context.elf_loading = true;
651 /*
652 * we call copy_pam_to_src to release global src here,
653 * we will map again when receive ack
654 */
655 if (cmd != NULL)
656 copy_pam_to_src(cmd->cmd_id, false);
657
658 if (async != NULL)
659 *async = true;
660 /* if send req to permservice success, do not free img buf */
661 return TEE_SUCCESS;
662 free_buf:
663 free_img_load_buf();
664 #else
665 /* if permserivce do not enable, then gtask will do elf verify */
666 (void)cmd;
667 (void)async;
668 elf_verify_reply reply;
669
670 ret = secure_elf_verify(req, &reply);
671 reply.verify_result = ret;
672 ret = process_register_elf(&reply, params);
673 if (ret != TEE_SUCCESS)
674 tloge("process register elf failed\n");
675
676 free_img_load_buf();
677 #endif
678 return ret;
679 }
680
load_secure_file_image(const smc_cmd_t * cmd,bool * async)681 TEE_Result load_secure_file_image(const smc_cmd_t *cmd, bool *async)
682 {
683 TEE_Result ret;
684 TEE_Param *params = NULL;
685 elf_verify_req req;
686
687 ret = load_secure_file_image_pre(cmd, ¶ms);
688 if (ret == RET_KEEP_LOADING)
689 return TEE_SUCCESS;
690 else if (ret != TEE_SUCCESS)
691 goto free_buf;
692
693 ret = img_unpack_copy_request_param(&req);
694 if (ret != TEE_SUCCESS)
695 goto free_buf;
696
697 /* we close elf file here, so libelf_verify can open this file */
698 ret = close_tmp_file();
699 if (ret != TEE_SUCCESS)
700 goto free_buf;
701
702 ret = tee_secure_img_unpack_req(&req, cmd, params, async);
703 if (ret != TEE_SUCCESS)
704 tloge("Failed to send unpack secure image request\n");
705 return ret;
706 free_buf:
707 free_img_load_buf();
708 return ret;
709 }
710
send_img_load_response(TEE_Result result)711 static void send_img_load_response(TEE_Result result)
712 {
713 /* reply to tzdriver */
714 set_tee_return_origin(&g_load_context.smc_cmd, TEE_ORIGIN_TEE);
715 set_tee_return(&g_load_context.smc_cmd, result);
716 ns_cmd_response(&g_load_context.smc_cmd);
717 }
718
check_register_elf_caller(uint32_t task_id)719 static TEE_Result check_register_elf_caller(uint32_t task_id)
720 {
721 spawn_uuid_t caller_uuid;
722 TEE_UUID perm_uuid = TEE_SERVICE_PERM;
723
724 if (getuuid(taskid_to_pid(task_id), &caller_uuid) != 0) {
725 tloge("get register elf caller uuid failed\n");
726 return TEE_ERROR_GENERIC;
727 }
728
729 if (TEE_MemCompare(&caller_uuid.uuid, &perm_uuid, sizeof(TEE_UUID)) == 0)
730 return TEE_SUCCESS;
731
732 return TEE_ERROR_NOT_SUPPORTED;
733 }
734
restore_load_img_context(TEE_Param ** params)735 static TEE_Result restore_load_img_context(TEE_Param **params)
736 {
737 set_load_ta_mode_global_ptr();
738
739 /* clear loading flag */
740 g_load_context.elf_loading = false;
741
742 /* for ta from tzdriver */
743 TEE_Result ret = tee_cmd_params_parse(&g_load_context.smc_cmd, params);
744 if (ret != TEE_SUCCESS) {
745 tloge("tee cmd params parse failed\n");
746 return ret;
747 }
748 return TEE_SUCCESS;
749 }
750
get_dyn_srv_config(const elf_verify_reply * reply,struct srv_adaptor_config_t * srv_config)751 static void get_dyn_srv_config(const elf_verify_reply *reply, struct srv_adaptor_config_t *srv_config)
752 {
753 srv_config->task_prio = DEFAULT_TASK_PRIO - 1;
754 srv_config->is_need_release_ta_res = reply->mani_ext.is_need_release_ta_res;
755 srv_config->is_need_create_msg = reply->mani_ext.is_need_create_msg;
756 srv_config->is_need_release_msg = reply->mani_ext.is_need_release_msg;
757 srv_config->crash_callback = reply->mani_ext.crash_callback;
758 }
759
process_register_elf_req(uint32_t cmd_id,uint32_t task_id,const uint8_t * msg_buf,uint32_t msg_size)760 int32_t process_register_elf_req(uint32_t cmd_id, uint32_t task_id, const uint8_t *msg_buf, uint32_t msg_size)
761 {
762 TEE_Result ret;
763 elf_verify_reply reply;
764 TEE_Param *params = NULL;
765
766 (void)cmd_id;
767 if (msg_buf == NULL || msg_size < sizeof (reply)) {
768 tloge("register elf req failed, recv invalid msg\n");
769 return GT_ERR_END_CMD;
770 }
771
772 /* check caller task_id is perm service */
773 if (check_register_elf_caller(task_id) != TEE_SUCCESS)
774 return GT_ERR_END_CMD;
775
776 errno_t rc = memcpy_s(&reply, sizeof(reply), msg_buf, sizeof(reply));
777 if (rc != EOK) {
778 tloge("copy register elf reply buf failed\n");
779 return GT_ERR_END_CMD;
780 }
781
782 ret = restore_load_img_context(¶ms);
783 if (ret != TEE_SUCCESS) {
784 tloge("restore load img context failed\n");
785 tee_unregister_dyn_config(&reply);
786 goto free_buf;
787 }
788
789 ret = process_register_elf(&reply, params);
790 if (ret != TEE_SUCCESS) {
791 tloge("process register elf failed\n");
792 goto free_buf;
793 }
794
795 free_buf:
796 send_img_load_response(ret);
797 free_img_load_buf();
798 if (reply.mani_ext.target_type == SRV_TARGET_TYPE) {
799 struct srv_adaptor_config_t srv_config = {0};
800 get_dyn_srv_config(&reply, &srv_config);
801 register_dynamic_task(&reply.srv_uuid, reply.service_name, &srv_config);
802 }
803 return (int)ret;
804 }
805
elf_verify_crash_callback(void)806 void elf_verify_crash_callback(void)
807 {
808 if (g_load_context.elf_loading == true) {
809 send_img_load_response(TEE_ERROR_TRUSTED_APP_LOAD_ERROR);
810 free_img_load_buf();
811 g_load_context.elf_loading = false;
812 }
813 }
814