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 #include "proc_tag.h"
13 
14 #include <errno.h>
15 #include <securec.h>
16 #include <sys/types.h>
17 #include <tee_client_list.h>
18 
19 #include "tee_log.h"
20 #include "tlogcat.h"
21 
22 #ifdef LOG_TAG
23 #undef LOG_TAG
24 #endif
25 #define LOG_TAG "tlogcat"
26 
27 struct DriverTagInfo {
28     uint8_t driverType;
29     char *tagName;
30     struct ListNode tagNode;
31 };
32 
33 static LIST_DECLARE(g_driverTagList);
34 
35 #define COMMON_DRV_SOURCE     0
36 #define SERVICE_NAME_MAX      100
37 
38 /* Description-"[*-%d]": * is ta's task name, and %d is sessionid&0xffff. */
39 #define TA_NAME_EXTENSION_LEN (SERVICE_NAME_MAX + 8)
40 
41 struct TaTagInfo {
42     struct TeeUuid uuid;
43     char *taTagName;
44     struct ListNode taTagNode;
45 };
46 
47 static LIST_DECLARE(g_taTagList);
48 
QueryTaTagNode(const struct TeeUuid * uuid)49 static char *QueryTaTagNode(const struct TeeUuid *uuid)
50 {
51     struct TaTagInfo *tagInfo = NULL;
52     struct ListNode *ptr = NULL;
53 
54     if (LIST_EMPTY(&g_taTagList)) {
55         return NULL;
56     }
57 
58     LIST_FOR_EACH(ptr, &g_taTagList) {
59         tagInfo = CONTAINER_OF(ptr, struct TaTagInfo, taTagNode);
60         if (memcmp(&(tagInfo->uuid), uuid, sizeof(*uuid)) != 0) {
61             continue;
62         }
63         return tagInfo->taTagName;
64     }
65 
66     return NULL;
67 }
68 
QueryDriverTagNode(uint8_t driverType)69 static char *QueryDriverTagNode(uint8_t driverType)
70 {
71     struct DriverTagInfo *tagInfo = NULL;
72     struct ListNode *ptr = NULL;
73 
74     if (LIST_EMPTY(&g_driverTagList)) {
75         return NULL;
76     }
77 
78     LIST_FOR_EACH(ptr, &g_driverTagList) {
79         tagInfo = CONTAINER_OF(ptr, struct DriverTagInfo, tagNode);
80         if (tagInfo->driverType != driverType) {
81             continue;
82         }
83         return tagInfo->tagName;
84     }
85 
86     return NULL;
87 }
88 
GetMiddleChar(const char * startStr,const char * endStr,char ** middleStr)89 static void GetMiddleChar(const char *startStr, const char *endStr, char **middleStr)
90 {
91     uint32_t subLen;
92     uint32_t i;
93 
94     *middleStr = NULL;
95 
96     /*
97      * Find the position of the tail '-' character.
98      * Reverses the position of the '-' character from the position of the ']' character.
99      */
100     char *p = (char *)endStr;
101     subLen = endStr - startStr + 1;
102     for (i = 0; i < subLen; i++) {
103         if (*p == '-') {
104             *middleStr = p;
105             break;
106         }
107         p--;
108     }
109 }
110 
GetLogItemTag(const struct LogItem * logItem,char * tagStr,uint32_t tagStrLen)111 static uint32_t GetLogItemTag(const struct LogItem *logItem, char *tagStr, uint32_t tagStrLen)
112 {
113     char *middleStr = NULL;
114     uint32_t tagLen;
115 
116     /* Ta log tag name is [taskname[-sessionid]] */
117     char *startStr = strchr((char *)logItem->logBuffer, '[');
118     char *endStr = strchr((char *)logItem->logBuffer, ']');
119 
120     bool conditon = ((startStr == NULL) || (endStr == NULL) || (endStr - startStr <= 1) ||
121                      (endStr - startStr + 1 > TA_NAME_EXTENSION_LEN));
122     if (conditon) {
123         tloge("wrong format log buffer\n");
124         return 0;
125     }
126 
127     /* Find the position of the tail '-' character. */
128     GetMiddleChar(startStr, endStr, &middleStr);
129     conditon = ((middleStr != NULL) && (middleStr - startStr - 1 > SERVICE_NAME_MAX));
130     if (conditon) {
131         tloge("too long task name\n");
132         return 0;
133     }
134 
135     tagLen = ((middleStr != NULL) ? (middleStr - startStr - 1) : (endStr - startStr - 1));
136     if (memcpy_s(tagStr, tagStrLen, startStr + 1, tagLen) != EOK) {
137         tloge("memcpy tag str is failed\n");
138         return 0;
139     }
140 
141     tagLen = ((tagStrLen == tagLen) ? (tagStrLen - 1) : tagLen);
142     tagStr[tagLen] = '\0';
143     return tagLen;
144 }
145 
InsertTaTagNode(char * tagName,uint32_t tagLen,const char ** logTag,const struct LogItem * logItem)146 static int32_t InsertTaTagNode(char *tagName, uint32_t tagLen, const char **logTag, const struct LogItem *logItem)
147 {
148     struct TaTagInfo *tagInfo = NULL;
149 
150     tagInfo = malloc(sizeof(*tagInfo));
151     if (tagInfo == NULL) {
152         tloge("malloc ta tag node failed\n");
153         return -1;
154     }
155 
156     errno_t rc = memcpy_s(&tagInfo->uuid, sizeof(tagInfo->uuid),
157         (struct TeeUuid *)logItem->uuid, sizeof(logItem->uuid));
158     if (rc != EOK) {
159         tloge("memcpy_s uuid error %d\n", rc);
160         goto FREE_TAG;
161     }
162 
163     tagName[tagLen - 1] = '\0';
164     tagInfo->taTagName = tagName;
165     *logTag = tagName;
166 
167     ListInit(&(tagInfo->taTagNode));
168     ListInsertTail(&g_taTagList, &(tagInfo->taTagNode));
169     /* cppcheck-suppress * */
170     return 0;
171 
172 FREE_TAG:
173     free(tagInfo);
174     tagInfo = NULL;
175     return -1;
176 }
177 
InsertDriverTagNode(char * tagName,uint32_t tagLen,const char ** logTag,const struct LogItem * logItem)178 static int32_t InsertDriverTagNode(char *tagName, uint32_t tagLen, const char **logTag, const struct LogItem *logItem)
179 {
180     struct DriverTagInfo *tagInfo = NULL;
181 
182     tagInfo = malloc(sizeof(*tagInfo));
183     if (tagInfo == NULL) {
184         tloge("malloc driver tag node failed\n");
185         return -1;
186     }
187 
188     tagName[tagLen - 1] = '\0';
189     tagInfo->tagName = tagName;
190     *logTag = tagName;
191 
192     tagInfo->driverType = logItem->logSourceType;
193 
194     ListInit(&(tagInfo->tagNode));
195     ListInsertTail(&g_driverTagList, &(tagInfo->tagNode));
196     /* cppcheck-suppress * */
197     return 0;
198 }
199 
QueryTagNode(bool isTa,const struct LogItem * logItem)200 static char *QueryTagNode(bool isTa, const struct LogItem *logItem)
201 {
202     if (isTa) {
203         return QueryTaTagNode((struct TeeUuid *)logItem->uuid);
204     } else {
205         return QueryDriverTagNode(logItem->logSourceType);
206     }
207 }
208 
InsertTagNode(bool isTa,char * tagName,uint32_t tagLen,const char ** logTag,const struct LogItem * logItem)209 static int32_t InsertTagNode(bool isTa, char *tagName, uint32_t tagLen,
210                              const char **logTag, const struct LogItem *logItem)
211 {
212     if (isTa) {
213         return InsertTaTagNode(tagName, tagLen, logTag, logItem);
214     } else {
215         return InsertDriverTagNode(tagName, tagLen, logTag, logItem);
216     }
217 }
218 
GetTagName(bool isTa,const struct LogItem * logItem,const char ** logTag)219 static bool GetTagName(bool isTa, const struct LogItem *logItem, const char **logTag)
220 {
221     char logItemTag[SERVICE_NAME_MAX + 1] = {0};
222 
223     char *tagName = QueryTagNode(isTa, logItem);
224     if (tagName != NULL) {
225         *logTag = tagName;
226         return true;
227     }
228 
229     uint32_t taTagTempLen = GetLogItemTag(logItem, logItemTag, (uint32_t)sizeof(logItemTag));
230     if (taTagTempLen == 0) {
231         return false;
232     }
233 
234     uint32_t tagLen = taTagTempLen + strlen("teeos-") + 1;
235     tagName = malloc(tagLen);
236     if (tagName == NULL) {
237         return false;
238     }
239 
240     int32_t ret = snprintf_s(tagName, tagLen, tagLen - 1, "%s-%s", "teeos", logItemTag);
241     if (ret < 0) {
242         tloge("snprintf_s for ta tag name is failed:0x%x\n", ret);
243         goto FREE_NAME;
244     }
245 
246     ret = InsertTagNode(isTa, tagName, tagLen, logTag, logItem);
247     if (ret < 0) {
248         tloge("insert tag node to list is failed:0x%x\n", ret);
249         goto FREE_NAME;
250     }
251 
252     return true;
253 
254 FREE_NAME:
255     free(tagName);
256     return false;
257 }
258 
JudgeLogTag(const struct LogItem * logItem,bool isTa,const char ** logTag)259 void JudgeLogTag(const struct LogItem *logItem, bool isTa, const char **logTag)
260 {
261     if (logItem == NULL || logTag == NULL) {
262         return;
263     }
264 
265     /* ta or special drv module from teeos need get proc log tag */
266     if (isTa || logItem->logSourceType > COMMON_DRV_SOURCE) {
267         /* write ta log to applocat file */
268         bool getTagRet = GetTagName(isTa, logItem, logTag);
269         if (!getTagRet) {
270             tloge("find ta task name is failed\n");
271             *logTag = LOG_TEEOS_TAG;
272         }
273         return;
274     }
275 
276     /* write teeos log to applogcat file */
277     *logTag = LOG_TEEOS_TAG;
278 }
279 
FreeTaTagNode(void)280 static void FreeTaTagNode(void)
281 {
282     struct ListNode *node = NULL;
283     struct ListNode *n = NULL;
284     struct TaTagInfo *taTagInfo = NULL;
285 
286     if (LIST_EMPTY(&g_taTagList)) {
287         return;
288     }
289 
290     LIST_FOR_EACH_SAFE(node, n, &g_taTagList) {
291         taTagInfo = CONTAINER_OF(node, struct TaTagInfo, taTagNode);
292         if (taTagInfo != NULL) {
293             ListRemoveTail(&taTagInfo->taTagNode);
294             if (taTagInfo->taTagName != NULL) {
295                 free(taTagInfo->taTagName);
296                 taTagInfo->taTagName = NULL;
297             }
298             free(taTagInfo);
299             taTagInfo = NULL;
300         }
301     }
302 }
303 
FreeDriverTagNode(void)304 static void FreeDriverTagNode(void)
305 {
306     struct ListNode *node = NULL;
307     struct ListNode *n = NULL;
308     struct DriverTagInfo *tagInfo = NULL;
309 
310     if (LIST_EMPTY(&g_driverTagList)) {
311         return;
312     }
313 
314     LIST_FOR_EACH_SAFE(node, n, &g_driverTagList) {
315         tagInfo = CONTAINER_OF(node, struct DriverTagInfo, tagNode);
316         if (tagInfo != NULL) {
317             ListRemoveTail(&tagInfo->tagNode);
318             if (tagInfo->tagName != NULL) {
319                 free(tagInfo->tagName);
320                 tagInfo->tagName = NULL;
321             }
322             free(tagInfo);
323             tagInfo = NULL;
324         }
325     }
326 }
327 
FreeTagNode(void)328 void FreeTagNode(void)
329 {
330     FreeDriverTagNode();
331     FreeTaTagNode();
332 }
333