• 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 #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, &param_type, &params);
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, &param_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(&param, &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, &params);
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, &params);
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(&params);
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