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 #define _GNU_SOURCE
13
14 #include "tee_tag.h"
15
16 #include <securec.h>
17 #include <pthread.h>
18 #include "tee_mem_mgmt_api.h"
19 #include "tee_init.h"
20 #include <ipclib.h>
21 #include <spawn_ext.h>
22 #include <unistd.h>
23
24 #define DRIVER_TAG_MAX_LEN 25
25 #define DRIVER_TAGS_NUM 40
26
27 static pthread_mutex_t g_driver_tag_lock = PTHREAD_MUTEX_INITIALIZER;
28
29 static uint8_t g_source_num = 0;
30
31 struct driver_tag_info {
32 uint8_t source_type;
33 const char *tag_name;
34 };
35
36 static struct driver_tag_info g_driver_tags[DRIVER_TAGS_NUM];
37
lock_tag_list(void)38 static int32_t lock_tag_list(void)
39 {
40 int32_t ret;
41
42 ret = pthread_mutex_lock(&g_driver_tag_lock);
43 if (ret == EOWNERDEAD) /* owner died, use consistent to recover and lock the mutex */
44 ret = pthread_mutex_consistent(&g_driver_tag_lock);
45
46 if (ret != 0)
47 printf("lock driver tag ret 0x%x\n", ret);
48
49 return ret;
50 }
51
unlock_tag_list(void)52 static void unlock_tag_list(void)
53 {
54 int32_t ret;
55
56 ret = pthread_mutex_unlock(&g_driver_tag_lock);
57 if (ret != 0)
58 printf("mutex unlock ret 0x%x\n", ret);
59
60 return;
61 }
62
insert_log_source(const char * driver_tag)63 static uint8_t insert_log_source(const char *driver_tag)
64 {
65 uint8_t source;
66
67 if (g_source_num == DRIVER_TAGS_NUM) {
68 printf("source type is overflow, max source type is %u\n", g_source_num);
69 return 0;
70 }
71
72 if (g_source_num == 0)
73 (void)memset_s(g_driver_tags, sizeof(g_driver_tags), 0, sizeof(g_driver_tags));
74
75 g_driver_tags[g_source_num].tag_name = driver_tag;
76 /* For source type 0 is common teeos log, the driver source type number starts from 1 */
77 g_driver_tags[g_source_num].source_type = g_source_num + 1;
78
79 source = g_driver_tags[g_source_num].source_type;
80 g_source_num++;
81 return source;
82 }
83
get_log_source(const char * driver_tag)84 uint8_t get_log_source(const char *driver_tag)
85 {
86 int32_t ret;
87 size_t len;
88 uint8_t source;
89 uint8_t i;
90
91 if (driver_tag == NULL)
92 return 0;
93
94 len = strnlen(driver_tag, DRIVER_TAG_MAX_LEN + 1);
95 if (len > DRIVER_TAG_MAX_LEN) {
96 printf("invalid driver tag len:%zu\n", len);
97 return 0;
98 }
99
100 ret = lock_tag_list();
101 if (ret != 0) {
102 source = 0;
103 return source;
104 }
105
106 for (i = 0; i <= g_source_num; i++) {
107 if (g_driver_tags[i].tag_name == NULL)
108 continue;
109
110 if (len != strnlen(g_driver_tags[i].tag_name, DRIVER_TAG_MAX_LEN + 1))
111 continue;
112
113 ret = TEE_MemCompare(driver_tag, g_driver_tags[i].tag_name, len);
114 if (ret == 0) {
115 unlock_tag_list();
116 return g_driver_tags[i].source_type;
117 }
118 }
119
120 source = insert_log_source(driver_tag);
121 unlock_tag_list();
122 return source;
123 }
124
125 #define SERVICE_NAME_MAX 100
126 #define OTHER_CHAR_LEN 2
127
get_log_tag(const char * driver_tag,const char * debug_prefix)128 char *get_log_tag(const char *driver_tag, const char *debug_prefix)
129 {
130 int32_t ret;
131 size_t len1;
132 size_t len2;
133
134 if (driver_tag == NULL || debug_prefix == NULL)
135 return NULL;
136
137 len1 = strnlen(driver_tag, DRIVER_TAG_MAX_LEN + 1);
138 if (len1 > DRIVER_TAG_MAX_LEN) {
139 printf("invalid driver tag len:%zu\n", len1);
140 return NULL;
141 }
142
143 len2 = strnlen(debug_prefix, SERVICE_NAME_MAX + 1);
144 if (len2 > SERVICE_NAME_MAX) {
145 printf("invalid debug prefix len:%zu\n", len2);
146 return NULL;
147 }
148
149 char *tag = TEE_Malloc(len1 + len2 + OTHER_CHAR_LEN, 0);
150 if (tag == NULL) {
151 printf("malloc tag buffer is null\n");
152 return NULL;
153 }
154
155 ret = snprintf_s(tag, len1 + len2 + OTHER_CHAR_LEN, len1 + len2 + OTHER_CHAR_LEN - 1,
156 "%s_%s", debug_prefix, driver_tag);
157 if (ret < 0) {
158 printf("snprintf_s for driver tag name is failed:0x%x\n", ret);
159 TEE_Free(tag);
160 return NULL;
161 }
162
163 return tag;
164 }
165
166 static bool g_use_tid_flag = false;
167
set_log_use_tid_flag(void)168 void set_log_use_tid_flag(void)
169 {
170 g_use_tid_flag = true;
171 }
172
173 /*
174 * this function is used to declare which thread print the log
175 * default use is the session_id of TA
176 * it can be changed when the user redefine this function
177 */
get_log_thread_tag(void)178 uint32_t get_log_thread_tag(void)
179 {
180 if (g_use_tid_flag) {
181 tid_t tid;
182 tid = gettid();
183 if (tid < 0)
184 return 0;
185 return tid;
186 } else {
187 return get_current_session_id();
188 }
189 }
190