• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.h"
14 #include <sys/stat.h>  /* for stat */
15 #include <dirent.h>
16 #include <limits.h>
17 
18 #include "securec.h"
19 #include "tc_ns_client.h"
20 #include "tee_log.h"
21 #include "secfile_load_agent.h"
22 
23 #ifdef LOG_TAG
24 #undef LOG_TAG
25 #endif
26 #define LOG_TAG "teecd_load_dynamic"
27 
28 #if defined(DYNAMIC_DRV_DIR) || defined(DYNAMIC_CRYPTO_DRV_DIR) || defined(DYNAMIC_SRV_DIR)
29 #define MAX_FILE_NAME_LEN 128
30 
OpenDynamicDir(const char * dynDir)31 static DIR *OpenDynamicDir(const char *dynDir)
32 {
33     DIR *dir = opendir(dynDir);
34     if (dir == NULL) {
35         tlogw("open drv dir: %" PUBLIC "s failed\n", dynDir);
36     }
37 
38     return dir;
39 }
40 
endsWith(const char * str,const char * suffix)41 static int32_t endsWith(const char *str, const char *suffix)
42 {
43     size_t strLen = strnlen(str, MAX_FILE_NAME_LEN);
44     size_t suffixLen = strnlen(suffix, MAX_FILE_NAME_LEN);
45     if (suffixLen > strLen || strLen == 0 || strLen >= MAX_FILE_NAME_LEN || suffixLen == 0) {
46         return -1;
47     }
48 
49     const char *ptr = str + (strLen - suffixLen);
50     if (strcmp(ptr, suffix) == 0) {
51         return 0;
52     }
53 
54     return -1;
55 }
56 
LoadOneFile(const char * dynDir,const struct dirent * dirFile,int32_t fd,uint32_t loadType)57 static int32_t LoadOneFile(const char *dynDir, const struct dirent *dirFile, int32_t fd, uint32_t loadType)
58 {
59     char name[MAX_FILE_NAME_LEN];
60     FILE *fp = NULL;
61     int32_t ret = -1;
62 
63     if (endsWith(dirFile->d_name, ".sec") != 0) {
64         tloge("file name does not end with .sec\n");
65         goto END;
66     }
67 
68     if (memset_s(name, sizeof(name), 0, sizeof(name)) != 0) {
69         tloge("mem set failed, name: %" PUBLIC "s, size: %" PUBLIC "u\n", name, (uint32_t)sizeof(name));
70         goto END;
71     }
72     if (strcat_s(name, MAX_FILE_NAME_LEN, dynDir) != 0) {
73         tloge("dir name too long: %" PUBLIC "s\n", dynDir);
74         goto END;
75     }
76     if (strcat_s(name, MAX_FILE_NAME_LEN, dirFile->d_name) != 0) {
77         tloge("drv name too long: %" PUBLIC "s\n", dirFile->d_name);
78         goto END;
79     }
80 
81     fp = fopen(name, "r");
82     if (fp == NULL) {
83         tloge("open drv failed: %" PUBLIC "s\n", name);
84         goto END;
85     }
86 
87     ret = LoadSecFile(fd, fp, loadType, NULL);
88     if (ret != 0) {
89         tloge("load dynamic failed: %" PUBLIC "s\n", name);
90     }
91 
92 END:
93     if (fp != NULL) {
94         (void)fclose(fp);
95     }
96 
97     return ret;
98 }
99 
LoadOneDynamicDir(int32_t fd,const char * dynDir,uint32_t loadType)100 static void LoadOneDynamicDir(int32_t fd, const char *dynDir, uint32_t loadType)
101 {
102     int32_t ret;
103     struct dirent *dirFile = NULL;
104 
105     DIR *dir = OpenDynamicDir(dynDir);
106     if (dir == NULL) {
107         tlogd("dynamic dir not exist\n");
108         return;
109     }
110     while ((dirFile = readdir(dir)) != NULL) {
111         if (dirFile->d_type != DT_REG) {
112             tlogd("no need to load\n");
113             continue;
114         }
115         ret = LoadOneFile(dynDir, dirFile, fd, loadType);
116         if (ret != 0) {
117             tlogd("load dynamic failed\n");
118             continue;
119         }
120     }
121     (void)closedir(dir);
122 }
123 
LoadDynamicCryptoDir(void)124 void LoadDynamicCryptoDir(void)
125 {
126 #ifdef DYNAMIC_CRYPTO_DRV_DIR
127     int32_t fd = GetSecLoadAgentFd();
128     LoadOneDynamicDir(fd, DYNAMIC_CRYPTO_DRV_DIR, LOAD_DYNAMIC_DRV);
129 #endif
130 }
131 
CheckPath(const char * drvPath,uint32_t drvPathLen,char * trustDrvPath)132 static int32_t CheckPath(const char *drvPath, uint32_t drvPathLen, char *trustDrvPath)
133 {
134     char trustDrvRootPath[PATH_MAX] = {0};
135     size_t optLen = strnlen(drvPath, MAX_FILE_NAME_LEN);
136     if (optLen == 0 || optLen >= MAX_FILE_NAME_LEN || drvPathLen != optLen) {
137         tloge("drv path is invalid\n");
138         return -1;
139     }
140 
141     size_t rootLen = strnlen(DYNAMIC_DRV_DIR, MAX_FILE_NAME_LEN);
142     if (rootLen == 0 || rootLen >= MAX_FILE_NAME_LEN) {
143         tloge("drv root path is invalid\n");
144         return -1;
145     }
146 
147     if (realpath(drvPath, trustDrvPath) == NULL) {
148         tloge("check realpath failed\n");
149         return -1;
150     }
151 
152     if (realpath(DYNAMIC_DRV_DIR, trustDrvRootPath) == NULL) {
153         tloge("check realpath failed\n");
154         return -1;
155     }
156 
157     rootLen = strnlen(trustDrvRootPath, MAX_FILE_NAME_LEN);
158     if (rootLen == 0 || rootLen >= MAX_FILE_NAME_LEN) {
159         tloge("drv root path is invalid\n");
160         return -1;
161     }
162 
163     optLen = strnlen(trustDrvPath, MAX_FILE_NAME_LEN);
164     if (optLen <= rootLen || optLen >= MAX_FILE_NAME_LEN) {
165         tloge("drv path is invalid\n");
166         return -1;
167     }
168 
169     if (strncmp(trustDrvPath, trustDrvRootPath, rootLen) != 0) {
170         tloge("drv path is invalid, %" PUBLIC "s, %" PUBLIC "s\n", trustDrvPath, trustDrvRootPath);
171         return -1;
172     }
173 
174     return 0;
175 }
176 
LoadDynamicDrvDir(const char * drvPath,uint32_t drvPathLen)177 void LoadDynamicDrvDir(const char *drvPath, uint32_t drvPathLen)
178 {
179 #ifdef DYNAMIC_DRV_DIR
180     int32_t fd = GetSecLoadAgentFd();
181     if (drvPathLen == 0 || drvPath == NULL) {
182         LoadOneDynamicDir(fd, DYNAMIC_DRV_DIR, LOAD_DYNAMIC_DRV);
183     } else {
184         char trustDrvPath[PATH_MAX] = {0};
185         if (CheckPath(drvPath, drvPathLen, trustDrvPath) != 0) {
186             tloge("check path failed\n");
187             return;
188         }
189         if (strcat_s(trustDrvPath, PATH_MAX, "/") != 0) {
190             tloge("add / to trust drv path failed\n");
191             return;
192         }
193 
194         LoadOneDynamicDir(fd, drvPath, LOAD_DYNAMIC_DRV);
195     }
196 #endif
197 }
198 
LoadDynamicSrvDir(void)199 void LoadDynamicSrvDir(void)
200 {
201 #ifdef DYNAMIC_SRV_DIR
202     int32_t fd = GetSecLoadAgentFd();
203     LoadOneDynamicDir(fd, DYNAMIC_SRV_DIR, LOAD_SERVICE);
204 #endif
205 }
206 #endif
207