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_load_dynamic_drv.h"
14 #include <dirent.h>
15 #include <limits.h>
16 #include <securec.h>
17 #include <sys/stat.h>
18 #include "secfile_load_agent.h"
19 #include "tc_ns_client.h"
20 #include "tee_log.h"
21
22 #ifdef LOG_TAG
23 #undef LOG_TAG
24 #endif
25 #define LOG_TAG "teecd_load_dynamic_elf"
26
27 #define MAX_FILE_NAME_LEN 128
28
LoadOneFile(const char * dynDir,const struct dirent * dirFile,int32_t fd,uint32_t loadType)29 static int32_t LoadOneFile(const char *dynDir, const struct dirent *dirFile, int32_t fd, uint32_t loadType)
30 {
31 char name[MAX_FILE_NAME_LEN];
32 FILE *fp = NULL;
33 int32_t ret = -1;
34
35 if (strcmp(dirFile->d_name, ".") == 0 || strcmp(dirFile->d_name, "..") == 0) {
36 tloge("no need to load\n");
37 goto END;
38 }
39
40 if (strstr(dirFile->d_name, ".sec") == NULL) {
41 tloge("only support sec file\n");
42 goto END;
43 }
44
45 if (memset_s(name, sizeof(name), 0, sizeof(name)) != 0) {
46 tloge("mem set failed, name: %s, size: %u\n", name, (uint32_t)sizeof(name));
47 goto END;
48 }
49 if (strcat_s(name, MAX_FILE_NAME_LEN, dynDir) != 0) {
50 tloge("dir name too long: %s\n", dynDir);
51 goto END;
52 }
53 if (strcat_s(name, MAX_FILE_NAME_LEN, dirFile->d_name) != 0) {
54 tloge("drv name too long: %s\n", dirFile->d_name);
55 goto END;
56 }
57
58 char realLoadFile[PATH_MAX + 1] = { 0 };
59 if (realpath(name, realLoadFile) == NULL) {
60 tloge("real path failed err=%d\n", errno);
61 goto END;
62 }
63
64 fp = fopen(realLoadFile, "r");
65 if (fp == NULL) {
66 tloge("open drv failed: %s\n", realLoadFile);
67 goto END;
68 }
69
70 ret = LoadSecFile(fd, fp, loadType, NULL);
71 if (ret != 0) {
72 tloge("load dynamic drv or srv failed: %s\n", realLoadFile);
73 }
74
75 END:
76 if (fp != NULL) {
77 (void)fclose(fp);
78 }
79
80 return ret;
81 }
82
LoadOneDynamicDir(int32_t fd,const char * dynDir,uint32_t loadType)83 static void LoadOneDynamicDir(int32_t fd, const char *dynDir, uint32_t loadType)
84 {
85 int32_t ret;
86 struct dirent *dirFile = NULL;
87
88 DIR *dir = opendir(dynDir);
89 if (dir == NULL) {
90 tlogi("tee dynamic dir not exist\n");
91 return;
92 }
93 while ((dirFile = readdir(dir)) != NULL) {
94 ret = LoadOneFile(dynDir, dirFile, fd, loadType);
95 if (ret != 0) {
96 tloge("load dynamic failed\n");
97 continue;
98 }
99 }
100 (void)closedir(dir);
101 }
102
LoadDynamicDir()103 void LoadDynamicDir()
104 {
105 int32_t fd = GetSecLoadAgentFd();
106
107 LoadOneDynamicDir(fd, DYNAMIC_DRV_DIR, LOAD_DYNAMIC_DRV);
108 LoadOneDynamicDir(fd, DYNAMIC_SRV_DIR, LOAD_SERVICE);
109 }