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