• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "tee_agent.h"
17 #include <dirent.h>
18 #include <errno.h>     /* for errno */
19 #include <fcntl.h>
20 #include <pthread.h>
21 #include <securec.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/ioctl.h> /* for ioctl */
26 #include <sys/mman.h>  /* for mmap */
27 #include <sys/stat.h>
28 #include <sys/statfs.h>
29 #include <sys/time.h>
30 #include <sys/types.h> /* for open close */
31 #include <unistd.h>
32 #include "secfile_load_agent.h"
33 #include "tc_ns_client.h"
34 #include "tcu_authentication.h"
35 #include "tee_ca_daemon.h"
36 #include "tee_client_api.h"
37 #include "tee_log.h"
38 #include "teec_compat.h"
39 
40 /* open file list head */
41 static struct OpenedFile *g_firstFile = (struct OpenedFile *)NULL;
42 
43 /* record the current g_userId */
44 static uint32_t g_userId;
SetCurrentUserId(uint32_t id)45 static void SetCurrentUserId(uint32_t id)
46 {
47     g_userId = id;
48 }
49 
GetCurrentUserId(void)50 static uint32_t GetCurrentUserId(void)
51 {
52     return g_userId;
53 }
54 
55 #define UID_MAX_LEN 16
56 
57 /* add to tail */
AddOpenFile(FILE * pFile)58 static int AddOpenFile(FILE *pFile)
59 {
60     struct OpenedFile *newFile = (struct OpenedFile *)malloc(sizeof(struct OpenedFile));
61     if (newFile == NULL) {
62         tloge("malloc OpenedFile failed\n");
63         return -1;
64     }
65     newFile->file = pFile;
66 
67     if (g_firstFile == NULL) {
68         g_firstFile   = newFile;
69         newFile->next = newFile;
70         newFile->prev = newFile;
71     } else {
72         if (g_firstFile->prev == NULL) {
73             tloge("the tail is null\n");
74             free(newFile);
75             return -1;
76         }
77         g_firstFile->prev->next = newFile;
78         newFile->prev           = g_firstFile->prev;
79         newFile->next           = g_firstFile;
80         g_firstFile->prev       = newFile;
81     }
82     return 0;
83 }
84 
DelOpenFile(struct OpenedFile * file)85 static void DelOpenFile(struct OpenedFile *file)
86 {
87     struct OpenedFile *next = NULL;
88 
89     if (file == NULL) {
90         return;
91     }
92     next = file->next;
93 
94     if (file == next) { /* only 1 node */
95         g_firstFile = NULL;
96     } else {
97         if (file->next == NULL || file->prev == NULL) {
98             tloge("the next or the prev is null\n");
99             return;
100         }
101         if (file == g_firstFile) {
102             g_firstFile = file->next;
103         }
104         next->prev       = file->prev;
105         file->prev->next = next;
106     }
107 }
108 
FindOpenFile(int fd,struct OpenedFile ** file)109 static int FindOpenFile(int fd, struct OpenedFile **file)
110 {
111     struct OpenedFile *p = g_firstFile;
112     int findFlag         = 0;
113 
114     if (p == NULL) {
115         return findFlag;
116     }
117 
118     do {
119         if (p->file != NULL) {
120             if (fileno(p->file) == fd) {
121                 findFlag = 1;
122                 break;
123             }
124         }
125         p = p->next;
126     } while (p != g_firstFile && p != NULL);
127 
128     if (!findFlag) {
129         p = NULL;
130     }
131     if (file != NULL) {
132         *file = p;
133     }
134     return findFlag;
135 }
136 
137 /* smc dev */
138 static int g_fsFd   = -1;
139 static int g_miscFd = -1;
140 
141 /*
142  * path:file or dir to change own
143  * flag: 0(dir);1(file)
144  */
ChownSecStorageDataToSystem(const char * path,int flag)145 static void ChownSecStorageDataToSystem(const char *path, int flag)
146 {
147     if (path == NULL) {
148         return;
149     }
150     /* check path is SEC_STORAGE_ROOT_DIR or SEC_STORAGE_DATA_DIR,
151      * we only need to change SEC_STORAGE_DATA_DIR from root to system
152      */
153     if (strstr(path, "sec_storage_data")) {
154         int ret = chown(path, AID_SYSTEM, AID_SYSTEM);
155         if (ret < 0) {
156             tloge("chown erro\n");
157         }
158         if (flag) {
159             ret = chmod(path, S_IRUSR | S_IWUSR);
160         } else {
161             ret = chmod(path, S_IRUSR | S_IWUSR | S_IXUSR);
162         }
163         if (ret < 0) {
164             tloge("chmod erro\n");
165         }
166     }
167 }
168 
CheckPathLen(const char * path,size_t pathLen)169 static int CheckPathLen(const char *path, size_t pathLen)
170 {
171     uint32_t i = 0;
172 
173     while (i < pathLen && path[i] != '\0') {
174         i++;
175     }
176     if (i >= pathLen) {
177         tloge("path is too long\n");
178         return -1;
179     }
180     return 0;
181 }
182 
183 /*
184  * path:file path name.
185  * e.g. sec_storage_data/app1/sub1/fileA.txt
186  * then CreateDir will make dir sec_storage_data, app1 and sub1.
187  */
CreateDir(const char * path,size_t pathLen)188 static int CreateDir(const char *path, size_t pathLen)
189 {
190     int32_t ret;
191 
192     ret = CheckPathLen(path, pathLen);
193     if (ret) {
194         return -1;
195     }
196 
197     char *pathTemp = strdup(path);
198     char *position  = pathTemp;
199 
200     if (pathTemp == NULL) {
201         tloge("strdup error\n");
202         return -1;
203     }
204 
205     if (strncmp(pathTemp, "/", 1) == 0) {
206         position++;
207     } else if (strncmp(pathTemp, "./", strlen("./")) == 0) {
208         position += strlen("./");
209     }
210 
211     for (; *position != '\0'; ++position) {
212         if (*position == '/') {
213             *position = '\0';
214 
215             if (access(pathTemp, F_OK) == 0) {
216                 *position = '/';
217                 continue;
218             }
219 
220             if (mkdir(pathTemp, ROOT_DIR_PERM) != 0) {
221                 tloge("mkdir %s fail\n", pathTemp);
222                 free(pathTemp);
223                 pathTemp = NULL;
224                 (void)pathTemp;
225                 return -1;
226             }
227 
228             ChownSecStorageDataToSystem(pathTemp, 0);
229             tlogv("for %s\n", pathTemp);
230             *position = '/';
231         }
232     }
233 
234     free(pathTemp);
235     pathTemp = NULL;
236     (void)pathTemp;
237     return 0;
238 }
239 
CheckFileNameAndPath(const char * name,const char * path)240 static int CheckFileNameAndPath(const char *name, const char *path)
241 {
242     if (name == NULL || path == NULL) {
243         return -1;
244     }
245 
246     if (strstr(name, FILE_NAME_INVALID_STR)) {
247         tloge("Invalid file name(file name contain ..)\n");
248         return -1;
249     }
250 
251     return 0;
252 }
253 
JoinFileNamePerso(const char * name,char * path,size_t pathLen)254 static int JoinFileNamePerso(const char *name, char *path, size_t pathLen)
255 {
256     errno_t rc;
257 
258     rc = strncpy_s(path, pathLen, USER_DATA_DIR, sizeof(USER_DATA_DIR));
259     if (rc != EOK) {
260         tloge("strncpy_s failed %d\n", rc);
261         return -1;
262     }
263 
264     rc = strncat_s(path, pathLen, name, strlen(name));
265     if (rc != EOK) {
266         tloge("strncat_s failed %d\n", rc);
267         return -1;
268     }
269 
270     return 0;
271 }
272 
JoinFileNameTransient(const char * name,char * path,size_t pathLen)273 static int JoinFileNameTransient(const char *name, char *path, size_t pathLen)
274 {
275     errno_t rc;
276     uint32_t userId = GetCurrentUserId();
277 
278     rc = strncpy_s(path, pathLen, USER_DATA_DIR, sizeof(USER_DATA_DIR));
279     if (rc != EOK) {
280         tloge("strncpy_s failed %d\n", rc);
281         return -1;
282     }
283 
284     if (userId != 0) {
285         char userPath[UID_MAX_LEN] = { 0 };
286         rc = snprintf_s(userPath, sizeof(userPath), sizeof(userPath) - 1, "%u/", userId);
287         if (rc == -1) {
288             tloge("snprintf_s failed %d\n", rc);
289             return -1;
290         }
291 
292         rc = strncat_s(path, pathLen, SFS_PARTITION_USER_SYMLINK, strlen(SFS_PARTITION_USER_SYMLINK));
293         if (rc != EOK) {
294             tloge("strncat_s failed %d\n", rc);
295             return -1;
296         }
297 
298         rc = strncat_s(path, pathLen, userPath, strlen(userPath));
299         if (rc != EOK) {
300             tloge("strncat_s failed %d\n", rc);
301             return -1;
302         }
303 
304         if (strlen(name) <= strlen(SFS_PARTITION_TRANSIENT)) {
305             tloge("name length is too small\n");
306             return -1;
307         }
308         rc = strncat_s(path, pathLen, name + strlen(SFS_PARTITION_TRANSIENT),
309                        (strlen(name) - strlen(SFS_PARTITION_TRANSIENT)));
310         if (rc != EOK) {
311             tloge("strncat_s failed %d\n", rc);
312             return -1;
313         }
314     } else {
315         rc = strncat_s(path, pathLen, name, strlen(name));
316         if (rc != EOK) {
317             tloge("strncat_s failed %d\n", rc);
318             return -1;
319         }
320     }
321 
322     return 0;
323 }
324 
JoinFileNamePersistent(const char * name,char * path,size_t pathLen)325 static int JoinFileNamePersistent(const char *name, char *path, size_t pathLen)
326 {
327     errno_t rc;
328 
329     rc = strncpy_s(path, pathLen, ROOT_DIR, sizeof(ROOT_DIR));
330     if (rc != EOK) {
331         tloge("strncpy_s failed %d\n", rc);
332         return -1;
333     }
334 
335     rc = strncat_s(path, pathLen, name, strlen(name));
336     if (rc != EOK) {
337         tloge("strncat_s failed %d\n", rc);
338         return -1;
339     }
340 
341     return 0;
342 }
343 
JoinFileNameDefault(const char * name,char * path,size_t pathLen)344 static int JoinFileNameDefault(const char *name, char *path, size_t pathLen)
345 {
346     errno_t rc;
347 
348     rc = strncpy_s(path, pathLen, SEC_STORAGE_ROOT_DIR, sizeof(SEC_STORAGE_ROOT_DIR));
349     if (rc != EOK) {
350         tloge("strncpy_s failed %d\n", rc);
351         return -1;
352     }
353 
354     rc = strncat_s(path, pathLen, name, strlen(name));
355     if (rc != EOK) {
356         tloge("strncat_s failed %d\n", rc);
357         return -1;
358     }
359 
360     return 0;
361 }
362 
363 /*
364  * example for JoinFileName
365  *
366  * name                         userId        path
367  * -------------------------------------------------------------------------
368  * abc/def                      DC          /sec_storage/abc/def
369  * sec_storage/abc/def          DC          /sec_storage/abc/def
370  * sec_storage_data/abc/def     0           /data/sec_storage_data/abc/def
371  * sec_storage_data/abc/def     1           /data/sec_storage_data/1/abc/def
372  */
JoinFileName(const char * name,char * path,size_t pathLen)373 static int JoinFileName(const char *name, char *path, size_t pathLen)
374 {
375     int ret;
376 
377     if (CheckFileNameAndPath(name, path)) {
378         return -1;
379     }
380 
381     /* If the path name does not start with sec_storage or sec_storage_data,
382      * add sec_storage str for the path
383      */
384     if (name == strstr(name, SFS_PARTITION_TRANSIENT_PERSO) || name == strstr(name, SFS_PARTITION_TRANSIENT_PRIVATE)) {
385         ret = JoinFileNamePerso(name, path, pathLen);
386     } else if (name == strstr(name, SFS_PARTITION_TRANSIENT)) {
387         ret = JoinFileNameTransient(name, path, pathLen);
388     } else if (name == strstr(name, SFS_PARTITION_PERSISTENT)) {
389         ret = JoinFileNamePersistent(name, path, pathLen);
390     } else {
391         ret = JoinFileNameDefault(name, path, pathLen);
392     }
393 
394     tlogv("joined path is \"%s\"\n", path);
395     return ret;
396 }
397 
IsValidFilePath(const char * path)398 static bool IsValidFilePath(const char *path)
399 {
400     if ((path == strstr(path, SEC_STORAGE_DATA_DIR)) || (path == strstr(path, SEC_STORAGE_DATA_USERS)) ||
401         (path == strstr(path, SEC_STORAGE_ROOT_DIR))) {
402         return true;
403     }
404 
405     tloge("path is invalid %s\n", path);
406     return false;
407 }
408 
GetRealFilePath(const char * originPath,char * trustPath,size_t tPathLen)409 static uint32_t GetRealFilePath(const char *originPath, char *trustPath, size_t tPathLen)
410 {
411     char *retPath = realpath(originPath, trustPath);
412     if (retPath == NULL) {
413         /* the file may be not exist, will create after */
414         if ((errno != ENOENT) && (errno != EACCES)) {
415             tloge("realpath %s failed: %s\n", originPath, strerror(errno));
416             return (uint32_t)errno;
417         }
418         /* check origin path */
419         if (!IsValidFilePath(originPath)) {
420             tloge("path %s is invalid\n", originPath);
421             return ENFILE;
422         }
423         errno_t rc = strncpy_s(trustPath, tPathLen, originPath, strlen(originPath));
424         if (rc != EOK) {
425             tloge("strncpy_s failed %d\n", rc);
426             return EPERM;
427         }
428     } else {
429         /* check real path */
430         if (!IsValidFilePath(trustPath)) {
431             tloge("path %s is invalid\n", trustPath);
432             return ENFILE;
433         }
434     }
435     return 0;
436 }
437 
438 static int UnlinkRecursive(const char *name);
UnlinkRecursiveDir(const char * name)439 static int UnlinkRecursiveDir(const char *name)
440 {
441     int fail          = 0;
442     char dn[PATH_MAX] = { 0 };
443     errno_t rc;
444 
445     /* a directory, so open handle */
446     DIR *dir = opendir(name);
447     if (dir == NULL) {
448         tloge("dir %s open failed\n", name);
449         return -1;
450     }
451 
452     /* recurse over components */
453     errno = 0;
454 
455     struct dirent *de = readdir(dir);
456 
457     while (de != NULL) {
458         if (!strncmp(de->d_name, "..", sizeof("..")) || !strncmp(de->d_name, ".", sizeof("."))) {
459             de = readdir(dir);
460             continue;
461         }
462         rc = snprintf_s(dn, sizeof(dn), sizeof(dn) - 1, "%s/%s", name, de->d_name);
463         if (rc == -1) {
464             tloge("snprintf_s failed %d\n", rc);
465             fail = 1;
466             break;
467         }
468 
469         if (UnlinkRecursive(dn) < 0) {
470             tloge("loop UnlinkRecursive() failed, there are read-only file\n");
471             fail = 1;
472             break;
473         }
474         errno = 0;
475         de    = readdir(dir);
476     }
477 
478     /* in case readdir or UnlinkRecursive failed */
479     if (fail || errno < 0) {
480         int save = errno;
481         closedir(dir);
482         errno = save;
483         tloge("fail is %d, errno is %d\n", fail, errno);
484         return -1;
485     }
486 
487     /* close directory handle */
488     if (closedir(dir) < 0) {
489         tloge("closedir %s failed, errno is %d\n", name, errno);
490         return -1;
491     }
492 
493     /* delete target directory */
494     if (rmdir(name) < 0) {
495         tloge("rmdir %s failed, errno is %d\n", name, errno);
496         return -1;
497     }
498     return 0;
499 }
500 
UnlinkRecursive(const char * name)501 static int UnlinkRecursive(const char *name)
502 {
503     struct stat st;
504 
505     /* is it a file or directory? */
506     if (lstat(name, &st) < 0) {
507         tloge("lstat %s failed, errno is %x\n", name, errno);
508         return -1;
509     }
510 
511     /* a file, so unlink it */
512     if (!S_ISDIR(st.st_mode)) {
513         if (unlink(name) < 0) {
514             tloge("unlink %s failed, errno is %d\n", name, errno);
515             return -1;
516         }
517         return 0;
518     }
519 
520     return UnlinkRecursiveDir(name);
521 }
522 
IsFileExist(const char * name)523 static int IsFileExist(const char *name)
524 {
525     struct stat statbuf;
526 
527     if (name == NULL) {
528         return 0;
529     }
530     if (stat(name, &statbuf)) {
531         if (errno == ENOENT) { /* file not exist */
532             tloge("file stat failed\n");
533             return 0;
534         }
535         return 1;
536     }
537 
538     return 1;
539 }
540 
DoOpenFile(const char * path,struct SecStorageType * transControl)541 static uint32_t DoOpenFile(const char *path, struct SecStorageType *transControl)
542 {
543     char trustPath[PATH_MAX] = { 0 };
544 
545     uint32_t rRet = GetRealFilePath(path, trustPath, sizeof(trustPath));
546     if (rRet) {
547         tloge("get real path failed. err=%u\n", rRet);
548         return rRet;
549     }
550 
551     FILE *pFile = fopen(trustPath, transControl->Args.Open.mode);
552     if (pFile == NULL) {
553         tloge("open file(%s) with flag(%s) failed: %s\n", trustPath, transControl->Args.Open.mode, strerror(errno));
554         return (uint32_t)errno;
555     }
556 
557     ChownSecStorageDataToSystem(trustPath, 1);
558     int ret = AddOpenFile(pFile);
559     if (ret) {
560         (void)fclose(pFile);
561         pFile = NULL;
562         tloge("add OpenedFile failed\n");
563         return ENOMEM;
564     }
565     transControl->ret = fileno(pFile); /* return fileno */
566     return 0;
567 }
568 
OpenWork(struct SecStorageType * transControl)569 static void OpenWork(struct SecStorageType *transControl)
570 {
571     uint32_t error;
572     char nameBuff[FILE_NAME_MAX_BUF] = { 0 };
573 
574     SetCurrentUserId(transControl->userId);
575 
576     tlogv("sec storage : open, file name:%s", (char *)(transControl->Args.Open.name));
577 
578     if (!JoinFileName((char *)(transControl->Args.Open.name), nameBuff, sizeof(nameBuff))) {
579         if (transControl->cmd == SEC_CREATE) {
580             /* create a exist file, remove it at first */
581             errno_t rc =
582                 strncpy_s(transControl->Args.Open.mode, sizeof(transControl->Args.Open.mode), "w+", sizeof("w+"));
583             if (rc != EOK) {
584                 tloge("strncpy_s failed %d\n", rc);
585                 error = ENOENT;
586                 goto ERROR;
587             }
588         } else {
589             if (IsFileExist(nameBuff) == 0) {
590                 /* open a nonexist file, return fail */
591                 tloge("file(%s) not exist, open failed\n", nameBuff);
592                 error = ENOENT;
593                 goto ERROR;
594             }
595         }
596 
597         /* mkdir -p for new create files */
598         if (CreateDir(nameBuff, sizeof(nameBuff))) {
599             error = (uint32_t)errno;
600             goto ERROR;
601         }
602 
603         error = DoOpenFile(nameBuff, transControl);
604         if (error) {
605             goto ERROR;
606         }
607     } else {
608         /* NEVER in this case */
609         transControl->ret = -1;
610     }
611     return;
612 
613 ERROR:
614     transControl->ret   = -1;
615     transControl->error = error;
616     return;
617 }
618 
CloseWork(struct SecStorageType * transControl)619 static void CloseWork(struct SecStorageType *transControl)
620 {
621     struct OpenedFile *selFile = NULL;
622 
623     tlogv("sec storage : close\n");
624 
625     if (FindOpenFile(transControl->Args.Close.fd, &selFile)) {
626         int ret = fclose(selFile->file);
627         if (ret == 0) {
628             tlogv("close file(%d) success\n", transControl->Args.Close.fd);
629             DelOpenFile(selFile);
630             free(selFile);
631             selFile = NULL;
632             (void)selFile;
633         } else {
634             tloge("close file(%d) failed: %s\n", transControl->Args.Close.fd, strerror(errno));
635             transControl->error = (uint32_t)errno;
636         }
637         transControl->ret = ret;
638     } else {
639         tloge("can't find opened file(fileno = %d)\n", transControl->Args.Close.fd);
640         transControl->ret   = -1;
641         transControl->error = EBADF;
642     }
643 }
644 
ReadWork(struct SecStorageType * transControl)645 static void ReadWork(struct SecStorageType *transControl)
646 {
647     struct OpenedFile *selFile = NULL;
648 
649     tlogv("sec storage : read count = %d\n", transControl->Args.Read.count);
650 
651     if (FindOpenFile(transControl->Args.Read.fd, &selFile)) {
652         size_t count = fread((void *)(transControl->Args.Read.buffer), 1, transControl->Args.Read.count, selFile->file);
653         transControl->ret = (int32_t)count;
654 
655         if (count < transControl->Args.Read.count) {
656             if (feof(selFile->file)) {
657                 transControl->ret2 = 0;
658                 tlogv("read end of file\n");
659             } else {
660                 transControl->ret2  = -1;
661                 transControl->error = (uint32_t)errno;
662                 tloge("read file failed: %s\n", strerror(errno));
663             }
664         } else {
665             transControl->ret2 = 0;
666             tlogv("read file success, content len=%lu\n", count);
667         }
668     } else {
669         transControl->ret   = 0;
670         transControl->ret2  = -1;
671         transControl->error = EBADF;
672         tloge("can't find opened file(fileno = %d)\n", transControl->Args.Read.fd);
673     }
674 }
675 
WriteWork(struct SecStorageType * transControl)676 static void WriteWork(struct SecStorageType *transControl)
677 {
678     struct OpenedFile *selFile = NULL;
679 
680     tlogv("sec storage : write count = %d\n", transControl->Args.Write.count);
681 
682     if (FindOpenFile(transControl->Args.Write.fd, &selFile)) {
683         size_t count = fwrite((void *)(transControl->Args.Write.buffer), 1,
684             transControl->Args.Write.count, selFile->file);
685         if (count < transControl->Args.Write.count) {
686             tloge("write file failed: %s\n", strerror(errno));
687             transControl->ret   = (int32_t)count;
688             transControl->error = (uint32_t)errno;
689             return;
690         }
691 
692         if (transControl->ret2 == SEC_WRITE_SSA) {
693             if (fflush(selFile->file) != 0) {
694                 tloge("fflush file failed: %s\n", strerror(errno));
695                 transControl->ret   = 0;
696                 transControl->error = (uint32_t)errno;
697             } else {
698                 transControl->ret = (int32_t)count;
699             }
700         } else {
701             transControl->ret   = (int32_t)count;
702             transControl->error = 0;
703         }
704     } else {
705         tloge("can't find opened file(fileno = %d)\n", transControl->Args.Write.fd);
706         transControl->ret   = 0;
707         transControl->error = EBADF;
708     }
709 }
710 
SeekWork(struct SecStorageType * transControl)711 static void SeekWork(struct SecStorageType *transControl)
712 {
713     struct OpenedFile *selFile = NULL;
714 
715     tlogv("sec storage : seek offset=%d, whence=%d\n", transControl->Args.Seek.offset, transControl->Args.Seek.whence);
716 
717     if (FindOpenFile(transControl->Args.Seek.fd, &selFile)) {
718         int ret = fseek(selFile->file, transControl->Args.Seek.offset, (int)transControl->Args.Seek.whence);
719         if (ret) {
720             tloge("seek file failed: %s\n", strerror(errno));
721             transControl->error = (uint32_t)errno;
722         } else {
723             tlogv("seek file success\n");
724         }
725         transControl->ret = ret;
726     } else {
727         tloge("can't find opened file(fileno = %d)\n", transControl->Args.Seek.fd);
728         transControl->ret   = -1;
729         transControl->error = EBADF;
730     }
731 }
732 
RemoveWork(struct SecStorageType * transControl)733 static void RemoveWork(struct SecStorageType *transControl)
734 {
735     char nameBuff[FILE_NAME_MAX_BUF] = { 0 };
736 
737     tlogv("sec storage : remove \"%s\"\n", (char *)(transControl->Args.Remove.name));
738 
739     SetCurrentUserId(transControl->userId);
740 
741     if (!JoinFileName((char *)(transControl->Args.Remove.name), nameBuff, sizeof(nameBuff))) {
742         int ret = UnlinkRecursive(nameBuff);
743         if (ret) {
744             tloge("remove file failed: %s\n", strerror(errno));
745             transControl->error = (uint32_t)errno;
746         } else {
747             tlogv("remove file success\n");
748         }
749         transControl->ret = ret;
750     } else {
751         transControl->ret = -1;
752     }
753 }
754 
TruncateWork(struct SecStorageType * transControl)755 static void TruncateWork(struct SecStorageType *transControl)
756 {
757     char nameBuff[FILE_NAME_MAX_BUF] = { 0 };
758 
759     tlogv("sec storage : truncate \"%s\", len=%d\n", (char *)(transControl->Args.Truncate.name),
760           transControl->Args.Truncate.len);
761 
762     SetCurrentUserId(transControl->userId);
763 
764     if (!JoinFileName((char *)(transControl->Args.Truncate.name), nameBuff, sizeof(nameBuff))) {
765         int ret = truncate(nameBuff, (long)transControl->Args.Truncate.len);
766         if (ret) {
767             tloge("truncate file failed: %s\n", strerror(errno));
768             transControl->error = (uint32_t)errno;
769         } else {
770             tlogv("truncate file success\n");
771         }
772         transControl->ret = ret;
773     } else {
774         transControl->ret = -1;
775     }
776 }
777 
RenameWork(struct SecStorageType * transControl)778 static void RenameWork(struct SecStorageType *transControl)
779 {
780     char nameBuff[FILE_NAME_MAX_BUF]  = { 0 };
781     char nameBuff2[FILE_NAME_MAX_BUF] = { 0 };
782 
783     SetCurrentUserId(transControl->userId);
784 
785     int joinRet1 = JoinFileName((char *)(transControl->Args.Rename.buffer), nameBuff, sizeof(nameBuff));
786     int joinRet2 = JoinFileName((char *)(transControl->Args.Rename.buffer) + transControl->Args.Rename.oldNameLen,
787                                 nameBuff2, sizeof(nameBuff2));
788     if (!joinRet1 && !joinRet2) {
789         int ret = rename(nameBuff, nameBuff2);
790         if (ret) {
791             tloge("rename file failed: %s\n", strerror(errno));
792             transControl->error = (uint32_t)errno;
793         } else {
794             tlogv("rename file success\n");
795         }
796         transControl->ret = ret;
797     } else {
798         transControl->ret = -1;
799     }
800 }
801 
802 #define MAXBSIZE 65536
803 
DoCopy(int fromFd,int toFd)804 static int DoCopy(int fromFd, int toFd)
805 {
806     int ret;
807     ssize_t rcount;
808     ssize_t wcount;
809 
810     char *buf = (char *)malloc(MAXBSIZE * sizeof(char));
811     if (buf == NULL) {
812         tloge("malloc buf failed\n");
813         return -1;
814     }
815     if (memset_s(buf, MAXBSIZE, 0, MAXBSIZE) != EOK) {
816         tloge("memset buf failed\n");
817         ret = -1;
818         goto OUT;
819     }
820 
821     rcount = read(fromFd, buf, MAXBSIZE);
822     while (rcount > 0) {
823         wcount = write(toFd, buf, (size_t)rcount);
824         if (rcount != wcount || wcount == -1) {
825             tloge("write file failed: %s\n", strerror(errno));
826             ret = -1;
827             goto OUT;
828         }
829         if (memset_s(buf, MAXBSIZE, 0, MAXBSIZE) != EOK) {
830             tloge("memset buf failed\n");
831             ret = -1;
832             goto OUT;
833         }
834         rcount = read(fromFd, buf, MAXBSIZE);
835     }
836 
837     if (rcount < 0) {
838         tloge("read file failed: %s\n", strerror(errno));
839         ret = -1;
840         goto OUT;
841     }
842 
843     /* fsync memory from kernel to disk */
844     ret = fsync(toFd);
845     if (ret != 0) {
846         /* fsync may be unsupport in some fs, for example:jffs2. */
847         if (errno == ENOSYS) {
848             free(buf);
849             return 0;
850         }
851         tloge("CopyFile:fsync file failed: %s\n", strerror(errno));
852         goto OUT;
853     }
854 
855 OUT:
856     free(buf);
857     return ret;
858 }
859 
CopyFile(const char * fromPath,const char * toPath)860 static int CopyFile(const char *fromPath, const char *toPath)
861 {
862     struct stat fromStat;
863     char realFromPath[PATH_MAX] = { 0 };
864     char realToPath[PATH_MAX]   = { 0 };
865 
866     uint32_t rRet = GetRealFilePath(fromPath, realFromPath, sizeof(realFromPath));
867     if (rRet) {
868         tloge("get real from path failed. err=%u\n", rRet);
869         return -1;
870     }
871 
872     rRet = GetRealFilePath(toPath, realToPath, sizeof(realToPath));
873     if (rRet) {
874         tloge("get real to path failed. err=%u\n", rRet);
875         return -1;
876     }
877 
878     int fromFd = open(realFromPath, O_RDONLY, 0);
879     if (fromFd == -1) {
880         tloge("open file %s failed: %s\n", realFromPath, strerror(errno));
881         return -1;
882     }
883 
884     int ret = fstat(fromFd, &fromStat);
885     if (ret == -1) {
886         tloge("stat file %s failed: %s\n", realFromPath, strerror(errno));
887         close(fromFd);
888         return ret;
889     }
890 
891     int toFd = open(realToPath, O_WRONLY | O_TRUNC | O_CREAT, fromStat.st_mode);
892     if (toFd == -1) {
893         tloge("stat file %s failed: %s\n", realToPath, strerror(errno));
894         close(fromFd);
895         return -1;
896     }
897 
898     ret = DoCopy(fromFd, toFd);
899     if (ret != 0) {
900         tloge("do copy from %s to %s failed\n", realFromPath, realToPath);
901     } else {
902         ChownSecStorageDataToSystem((char *)realToPath, 1);
903     }
904 
905     close(fromFd);
906     close(toFd);
907     return ret;
908 }
909 
CopyWork(struct SecStorageType * transControl)910 static void CopyWork(struct SecStorageType *transControl)
911 {
912     char fromPath[FILE_NAME_MAX_BUF] = { 0 };
913     char toPath[FILE_NAME_MAX_BUF]   = { 0 };
914 
915     SetCurrentUserId(transControl->userId);
916 
917     int joinRet1 = JoinFileName((char *)(transControl->Args.Cp.buffer), fromPath, sizeof(fromPath));
918     int joinRet2 = JoinFileName((char *)(transControl->Args.Cp.buffer) + transControl->Args.Cp.fromPathLen, toPath,
919                                 sizeof(toPath));
920     if (!joinRet1 && !joinRet2) {
921         int ret = CopyFile(fromPath, toPath);
922         if (ret) {
923             tloge("copy file failed: %s\n", strerror(errno));
924             transControl->error = (uint32_t)errno;
925         } else {
926             tlogv("copy file success\n");
927         }
928         transControl->ret = ret;
929     } else {
930         transControl->ret = -1;
931     }
932 }
933 
FileInfoWork(struct SecStorageType * transControl)934 static void FileInfoWork(struct SecStorageType *transControl)
935 {
936     struct OpenedFile *selFile = NULL;
937     struct stat statBuff;
938 
939     tlogv("sec storage : file info\n");
940 
941     transControl->Args.Info.fileLen = transControl->Args.Info.curPos = 0;
942 
943     if (FindOpenFile(transControl->Args.Info.fd, &selFile)) {
944         int ret = fstat(transControl->Args.Info.fd, &statBuff);
945         if (ret == 0) {
946             transControl->Args.Info.fileLen = (uint32_t)statBuff.st_size;
947             transControl->Args.Info.curPos  = (uint32_t)ftell(selFile->file);
948         } else {
949             tloge("fstat file failed: %s\n", strerror(errno));
950             transControl->error = (uint32_t)errno;
951         }
952         transControl->ret = ret;
953     } else {
954         transControl->ret   = -1;
955         transControl->error = EBADF;
956     }
957 }
958 
FileAccessWork(struct SecStorageType * transControl)959 static void FileAccessWork(struct SecStorageType *transControl)
960 {
961     int ret;
962 
963     tlogv("sec storage : file access\n");
964 
965     if (transControl->cmd == SEC_ACCESS) {
966         SetCurrentUserId(transControl->userId);
967 
968         char nameBuff[FILE_NAME_MAX_BUF] = { 0 };
969         if (!JoinFileName((char *)(transControl->Args.Access.name), nameBuff, sizeof(nameBuff))) {
970             ret = access(nameBuff, transControl->Args.Access.mode);
971             if (ret < 0) {
972                 tloge("access file(%s) mode(%d) failed: %s\n", nameBuff, transControl->Args.Access.mode,
973                       strerror(errno));
974             }
975             transControl->ret   = ret;
976             transControl->error = (uint32_t)errno;
977         } else {
978             transControl->ret = -1;
979         }
980     } else {
981         ret = access((char *)(transControl->Args.Access.name), transControl->Args.Access.mode);
982         if (ret < 0) {
983             tloge("access2 file(%s) mode(%d) failed: %s\n", (char *)transControl->Args.Access.name,
984                   transControl->Args.Access.mode, strerror(errno));
985         }
986         transControl->ret   = ret;
987         transControl->error = (uint32_t)errno;
988     }
989 }
990 
FsyncWork(struct SecStorageType * transControl)991 static void FsyncWork(struct SecStorageType *transControl)
992 {
993     struct OpenedFile *selFile = NULL;
994 
995     tlogv("sec storage : file fsync\n");
996 
997     /* opened file */
998     if (transControl->Args.Fsync.fd && FindOpenFile(transControl->Args.Fsync.fd, &selFile)) {
999         /* first,flush memory from user to kernel */
1000         int ret = fflush(selFile->file);
1001         if (ret != 0) {
1002             tloge("fsync:fflush file failed: %s\n", strerror(errno));
1003             transControl->ret   = -1;
1004             transControl->error = (uint32_t)errno;
1005             return;
1006         }
1007 
1008         /* second,fsync memory from kernel to disk */
1009         int fd  = fileno(selFile->file);
1010         ret = fsync(fd);
1011         /* fsync may be unsupport in some fs, for example:jffs2. */
1012         if (ret != 0 && errno != ENOSYS) {
1013             tloge("fsync:fsync file failed: %s\n", strerror(errno));
1014             transControl->ret   = -1;
1015             transControl->error = (uint32_t)errno;
1016             return;
1017         }
1018 
1019         transControl->ret = 0;
1020         tlogv("fsync file(%d) success\n", transControl->Args.Fsync.fd);
1021     } else {
1022         tloge("can't find opened file(fileno = %d)\n", transControl->Args.Fsync.fd);
1023         transControl->ret   = -1;
1024         transControl->error = EBADF;
1025     }
1026 }
1027 
DiskUsageWork(struct SecStorageType * transControl)1028 static void DiskUsageWork(struct SecStorageType *transControl)
1029 {
1030     struct statfs st;
1031     uint32_t dataRemain;
1032     uint32_t secStorageRemain;
1033 
1034     tlogv("sec storage : disk usage\n");
1035 
1036     if (statfs("/storage/data", &st) < 0) {
1037         tloge("statfs /data failed, err=%s\n", strerror(errno));
1038         goto ERROR;
1039     }
1040 
1041     dataRemain = (long)st.f_bfree * (long)st.f_bsize / K_BYTES;
1042 
1043     if (statfs("/storage/sec_storage", &st) < 0) {
1044         tloge("statfs /sec_storage failed, err=%s\n", strerror(errno));
1045         goto ERROR;
1046     }
1047 
1048     secStorageRemain = (long)st.f_bfree * (long)st.f_bsize / K_BYTES;
1049 
1050     transControl->ret                       = 0;
1051     transControl->Args.DiskUsage.data       = dataRemain;
1052     transControl->Args.DiskUsage.secStorage = secStorageRemain;
1053     return;
1054 
1055 ERROR:
1056     transControl->ret   = -1;
1057     transControl->error = (uint32_t)errno;
1058 }
1059 
DeleteAllWork(struct SecStorageType * transControl)1060 static void DeleteAllWork(struct SecStorageType *transControl)
1061 {
1062     int ret;
1063     char path[FILE_NAME_MAX_BUF] = { 0 };
1064     char *pathIn                 = (char *)(transControl->Args.DeleteAll.path);
1065     SetCurrentUserId(transControl->userId);
1066 
1067     tlogv("sec storage : delete path \"%s\" , userid:%d\n", (char *)(transControl->Args.DeleteAll.path),
1068           transControl->userId);
1069 
1070     ret = strncpy_s(path, FILE_NAME_MAX_BUF, USER_DATA_DIR, sizeof(USER_DATA_DIR));
1071     if (ret != EOK) {
1072         tloge("strncpy_s failed %d\n", ret);
1073         transControl->ret = -1;
1074         return;
1075     }
1076 
1077     ret = JoinFileNamePerso(pathIn, path, sizeof(path));
1078     if (ret != EOK) {
1079         tloge("join name failed %d\n", ret);
1080         transControl->ret = -1;
1081         return;
1082     }
1083 
1084     tlogv("sec storage : joint delete path \"%s\"\n", path);
1085 
1086     ret = UnlinkRecursive(path);
1087     if (ret) {
1088         tloge("delete file failed: %s\n", strerror(errno));
1089         transControl->error = (uint32_t)errno;
1090     } else {
1091         tloge("delete file success\n");
1092     }
1093     transControl->ret = ret;
1094 }
1095 
IsUserDataReady(void)1096 static int IsUserDataReady(void)
1097 {
1098     if (access(SEC_STORAGE_DATA_DIR, F_OK) == 0) {
1099         tlogv("userdata is ready from path: %s\n", SEC_STORAGE_DATA_DIR);
1100         return 1;
1101     }
1102     tloge("userdata is not ready from path: %s\n", SEC_STORAGE_DATA_DIR);
1103     return 0;
1104 }
1105 
1106 typedef void (*FsWorkFunc)(struct SecStorageType *transControl);
1107 typedef struct {
1108     FsCmdType cmd;
1109     FsWorkFunc fn;
1110 } FsWorkTbl;
1111 
1112 static const FsWorkTbl g_fsWorkTbl[] = {
1113     { SEC_OPEN, OpenWork },           { SEC_CLOSE, CloseWork },
1114     { SEC_READ, ReadWork },           { SEC_WRITE, WriteWork },
1115     { SEC_SEEK, SeekWork },           { SEC_REMOVE, RemoveWork },
1116     { SEC_TRUNCATE, TruncateWork },   { SEC_RENAME, RenameWork },
1117     { SEC_CREATE, OpenWork },         { SEC_INFO, FileInfoWork },
1118     { SEC_ACCESS, FileAccessWork },   { SEC_ACCESS2, FileAccessWork },
1119     { SEC_FSYNC, FsyncWork },         { SEC_CP, CopyWork },
1120     { SEC_DISKUSAGE, DiskUsageWork }, { SEC_DELETE_ALL, DeleteAllWork },
1121 };
1122 
FsWorkThread(void * control)1123 static void *FsWorkThread(void *control)
1124 {
1125     struct SecStorageType *transControl = NULL;
1126     int ret;
1127 
1128     if (control == NULL) {
1129         return NULL;
1130     }
1131     transControl = (struct SecStorageType *)control;
1132 
1133     if (g_fsFd == -1) {
1134         tloge("fs is not open\n");
1135         return NULL;
1136     }
1137 
1138     transControl->magic = AGENT_FS_ID;
1139     while (1) {
1140         tlogv("++ fs agent loop ++\n");
1141         ret = ioctl(g_fsFd, (int)TC_NS_CLIENT_IOCTL_WAIT_EVENT, AGENT_FS_ID);
1142         if (ret) {
1143             tloge("fs agent  wait event failed\n");
1144             break;
1145         }
1146 
1147         tlogv("fs agent wake up and working!!\n");
1148 
1149         if (IsUserDataReady() == 0) {
1150             transControl->ret = -1;
1151             tloge("do secure storage while userdata is not ready, skip!\n");
1152             goto FILE_WORK_DONE;
1153         }
1154 
1155         if ((transControl->cmd < SEC_MAX) && (g_fsWorkTbl[transControl->cmd].fn != NULL)) {
1156             g_fsWorkTbl[transControl->cmd].fn(transControl);
1157         } else {
1158             tloge("fs agent error cmd:transControl->cmd=%x\n", transControl->cmd);
1159         }
1160 
1161     FILE_WORK_DONE:
1162         Barriers();
1163         transControl->magic = AGENT_FS_ID;
1164         Barriers();
1165         ret = ioctl(g_fsFd, (int)TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, AGENT_FS_ID);
1166         if (ret) {
1167             tloge("fs agent send reponse failed\n");
1168             break;
1169         }
1170         tlogv("-- fs agent loop --\n");
1171     }
1172 
1173     return NULL;
1174 }
1175 
GetTimeWork(struct MiscControlType * transControl)1176 static void GetTimeWork(struct MiscControlType *transControl)
1177 {
1178     struct timeval timeVal;
1179 
1180     if (gettimeofday(&timeVal, NULL) == 0) {
1181         transControl->ret                  = 0;
1182         transControl->Args.GetTime.seconds = timeVal.tv_sec;
1183         transControl->Args.GetTime.millis  = (timeVal.tv_usec / USEC_PER_MSEC);
1184         struct tm *tstruct                 = NULL;
1185 
1186         tstruct = localtime(&(timeVal.tv_sec));
1187         if (tstruct != NULL) {
1188             /* year(from 1900) months(0~11) days hour min second */
1189             errno_t rc = snprintf_s(transControl->Args.GetTime.timeStr, sizeof(transControl->Args.GetTime.timeStr),
1190                 sizeof(transControl->Args.GetTime.timeStr) - 1, "%04d-%02d-%02d %02d:%02d:%02d.%03d ",
1191                 tstruct->tm_year + TIME_START_YEAR, tstruct->tm_mon + 1, tstruct->tm_mday, tstruct->tm_hour,
1192                 tstruct->tm_min, tstruct->tm_sec, (int)(timeVal.tv_usec / USEC_PER_MSEC));
1193             if (rc == -1) {
1194                 transControl->ret = -1;
1195                 tloge("snprintf_s error %d\n", rc);
1196             }
1197         } else {
1198             tloge("get localtiem error\n");
1199         }
1200     } else {
1201         transControl->ret                  = -1;
1202         transControl->Args.GetTime.seconds = 0;
1203         transControl->Args.GetTime.millis  = 0;
1204     }
1205 }
1206 
MiscWorkThread(void * control)1207 static void *MiscWorkThread(void *control)
1208 {
1209     struct MiscControlType *transControl = NULL;
1210 
1211     if (control == NULL) {
1212         return NULL;
1213     }
1214     transControl = (struct MiscControlType *)control;
1215 
1216     if (g_miscFd == -1) {
1217         tloge("misc file is not open\n");
1218         return NULL;
1219     }
1220 
1221     transControl->magic = AGENT_MISC_ID;
1222     while (1) {
1223         tlogv("++ misc agent loop ++\n");
1224         int ret = ioctl(g_miscFd, (int)TC_NS_CLIENT_IOCTL_WAIT_EVENT, AGENT_MISC_ID);
1225         if (ret) {
1226             tloge("misc agent wait event failed\n");
1227             break;
1228         }
1229 
1230         tlogv("misc agent wake up and working!!\n");
1231         switch (transControl->cmd) {
1232             case SEC_GET_TIME:
1233                 tlogv("sec get time of day\n");
1234                 GetTimeWork(transControl);
1235                 break;
1236             default:
1237                 tloge("misc agent error cmd\n");
1238                 break;
1239         }
1240         Barriers();
1241         transControl->magic = AGENT_MISC_ID;
1242         Barriers();
1243         ret = ioctl(g_miscFd, (int)TC_NS_CLIENT_IOCTL_SEND_EVENT_RESPONSE, AGENT_MISC_ID);
1244         if (ret) {
1245             tloge("misc agent send reponse failed\n");
1246             break;
1247         }
1248         tlogv("-- misc agent loop --\n");
1249     }
1250 
1251     return NULL;
1252 }
1253 
AgentInit(unsigned int id,uint8_t ** control)1254 static int AgentInit(unsigned int id, uint8_t **control)
1255 {
1256     int ret;
1257     struct AgentIoctlArgs args = { 0 };
1258 
1259     if (control == NULL) {
1260         return -1;
1261     }
1262     int fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR);
1263     if (fd < 0) {
1264         tloge("open tee client dev failed, fd is %d\n", fd);
1265         return -1;
1266     }
1267 
1268     /* register agent */
1269     args.id         = id;
1270     args.bufferSize = TRANS_BUFF_SIZE;
1271     ret             = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_REGISTER_AGENT, &args);
1272     if (ret) {
1273         (void)close(fd);
1274         tloge("ioctl failed\n");
1275         return -1;
1276     }
1277 
1278     *control = (uint8_t *)args.buffer;
1279     return fd;
1280 }
1281 
AgentExit(unsigned int id,int fd)1282 static void AgentExit(unsigned int id, int fd)
1283 {
1284     int ret;
1285 
1286     if (fd == -1) {
1287         return;
1288     }
1289 
1290     ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT, id);
1291     if (ret) {
1292         tloge("ioctl failed\n");
1293     }
1294 
1295     (void)close(fd);
1296 }
1297 
1298 enum LateInitIndex {
1299     FS_LATE_INIT = 0x1,
1300 };
1301 
1302 #define SLEEP_TIME (100 * 1000 * 1000)
InitLateWorkThread(void * dummy)1303 static void *InitLateWorkThread(void *dummy)
1304 {
1305     unsigned int index            = 0;
1306     struct timespec ts;
1307     ts.tv_sec  = 0;
1308     ts.tv_nsec = SLEEP_TIME;
1309 
1310     (void)dummy;
1311     tlogd("now start to late init\n");
1312 
1313     int fd = open(TC_NS_CLIENT_DEV_NAME, O_RDWR);
1314     if (fd < 0) {
1315         tloge("open tee client dev failed, fd is %d\n", fd);
1316         return NULL;
1317     }
1318     while (true) {
1319         nanosleep(&ts, NULL);
1320         if (IsUserDataReady() == 1) {
1321             index = FS_LATE_INIT;
1322             break;
1323         }
1324         tloge("userdata is not ready, sleep!\n");
1325     }
1326 
1327     int ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_LATEINIT, index);
1328     if (ret) {
1329         tloge("failed to set late init.\n");
1330     }
1331 
1332     close(fd);
1333     return NULL;
1334 }
1335 
1336 static struct SecStorageType *g_fsControl                = NULL;
1337 static struct MiscControlType *g_miscControl             = NULL;
1338 static struct SecAgentControlType *g_secLoadAgentControl = NULL;
1339 
1340 static int g_fsThreadFlag = 0;
1341 
ProcessAgentInit(void)1342 static int ProcessAgentInit(void)
1343 {
1344     int ret;
1345 
1346     g_fsThreadFlag = 1;
1347     g_fsFd = AgentInit(AGENT_FS_ID, (uint8_t **)(&g_fsControl));
1348     if (g_fsFd < 0) {
1349         tloge("fs agent init failed\n");
1350         g_fsThreadFlag = 0;
1351     }
1352 
1353     g_miscFd = AgentInit(AGENT_MISC_ID, (uint8_t **)(&g_miscControl));
1354     if (g_miscFd < 0) {
1355         tloge("misc agent init failed\n");
1356         goto ERROR1;
1357     }
1358 
1359     ret = AgentInit(SECFILE_LOAD_AGENT_ID, (uint8_t **)(&g_secLoadAgentControl));
1360     if (ret < 0) {
1361         tloge("secfile load agent init failed\n");
1362         goto ERROR2;
1363     }
1364 
1365     SetSecLoadAgentFd(ret);
1366     tloge("processAgent init ok\n");
1367 
1368     return 0;
1369 ERROR2:
1370     AgentExit(AGENT_MISC_ID, g_miscFd);
1371     g_miscFd      = -1;
1372     g_miscControl = NULL;
1373 
1374 ERROR1:
1375     if (g_fsThreadFlag == 1) {
1376         AgentExit(AGENT_FS_ID, g_fsFd);
1377         g_fsFd         = -1;
1378         g_fsControl    = NULL;
1379         g_fsThreadFlag = 0;
1380     }
1381     return -1;
1382 }
1383 
ProcessAgentExit(void)1384 static void ProcessAgentExit(void)
1385 {
1386     if (g_fsThreadFlag == 1) {
1387         AgentExit(AGENT_FS_ID, g_fsFd);
1388         g_fsFd      = -1;
1389         g_fsControl = NULL;
1390     }
1391 
1392     AgentExit(AGENT_MISC_ID, g_miscFd);
1393     g_miscFd      = -1;
1394     g_miscControl = NULL;
1395 
1396     AgentExit(SECFILE_LOAD_AGENT_ID, GetSecLoadAgentFd());
1397     SetSecLoadAgentFd(-1);
1398     g_secLoadAgentControl = NULL;
1399 }
1400 
main(int argc,char ** argv)1401 int main(int argc, char **argv)
1402 {
1403     pthread_t fsThread               = (pthread_t)-1;
1404     pthread_t secfileLoadAgentThread = (pthread_t)-1;
1405     pthread_t miscThread             = (pthread_t)-1;
1406     pthread_t lateInitThread         = (pthread_t)-1;
1407 
1408     TcuAuthentication();
1409 
1410     int ret = ProcessAgentInit();
1411     if (ret) {
1412         return ret;
1413     }
1414 
1415     if (g_fsThreadFlag == 1) {
1416         (void)pthread_create(&fsThread, NULL, FsWorkThread, g_fsControl);
1417         tloge("FsWorkThread create ok\n");
1418     }
1419 
1420     (void)pthread_create(&secfileLoadAgentThread, NULL, SecfileLoadAgentThread, g_secLoadAgentControl);
1421 
1422     (void)pthread_create(&miscThread, NULL, MiscWorkThread, g_miscControl);
1423     (void)pthread_create(&lateInitThread, NULL, InitLateWorkThread, NULL);
1424 
1425     (void)pthread_join(lateInitThread, NULL);
1426     if (g_fsThreadFlag == 1) {
1427         (void)pthread_join(fsThread, NULL);
1428     }
1429     (void)pthread_join(secfileLoadAgentThread, NULL);
1430     (void)pthread_join(miscThread, NULL);
1431 
1432     ProcessAgentExit();
1433     return 0;
1434 }
1435