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 }