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