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 "perm_srv_ta_config.h"
13 #include <string.h>
14 #include <securec.h>
15 #include <tee_ext_api.h>
16 #include <tee_log.h>
17 #include <timer_export.h>
18 #include <openssl/asn1.h>
19 #include "target_type.h"
20 #include "tee_mem_mgmt_api.h" /* TEE_Malloc */
21 #include "perm_srv_ta_crl.h"
22 #include "permission_config.h"
23
24 #define UINT8_TYPE_BITS_LEN 8U
25 #define ASN1_TLV_TAG_OFFSET 1 /* 1 byte for tag */
26 #define TLV_LEN_OFFSET 2
27 #define TLV_VALUE_OFFSET 3 /* 1 byte for tag, 2 bytes for len */
28 #define TLV_MAX_LEN (0xffff + TLV_VALUE_OFFSET) /* 3 is offset value */
29 #define POS_ARRAY_SIZE 5
30 #define H_L_ERROR_NUM_VAL (-1)
31
32 #define BYTE_COUNT_IN_UUID 16
33 #define UUID_FORMAT_STRLEN 37
34
35 #define POLICY_VER_XML2TLV_PARSE_INDEX 1 /* tool type for parse xml */
36 #define XML2TLV_PY_VALUE (1 << POLICY_VER_XML2TLV_PARSE_INDEX) /* python parse xml */
37 #define XML2TLV_JAR_VALUE (0 << POLICY_VER_XML2TLV_PARSE_INDEX) /* jar parse xml */
38 #define XML2TLV_PARSE_BIT_MAP (1 << POLICY_VER_XML2TLV_PARSE_INDEX)
39
40 static dlist_head(g_config_list);
41 static pthread_mutex_t g_config_list_lock = PTHREAD_MUTEX_INITIALIZER;
42
43 #define BITS_OF_BYTE 8
44 #define DYN_CONFING_TAG "gpd.ta.dynConf"
45
byte_to_integer(const uint8_t * bytes,size_t len,size_t val_size)46 static uint32_t byte_to_integer(const uint8_t *bytes, size_t len, size_t val_size)
47 {
48 uint32_t res = 0;
49 if (bytes == NULL || len < val_size)
50 return 0;
51
52 for (size_t i = 0; i < val_size; ++i)
53 res = (res << BITS_OF_BYTE) + bytes[i];
54
55 return res;
56 }
57
58 #define ALP_TO_DIGIT_GAP 10
asc2hex(char a)59 static int8_t asc2hex(char a)
60 {
61 bool is_digital = (a >= '0' && a <= '9');
62 bool is_lower_letters = (a >= 'a' && a <= 'f');
63 bool is_bigger_letters = (a >= 'A' && a <= 'F');
64
65 if (is_digital)
66 return a - '0';
67 else if (is_lower_letters)
68 return (a - 'a') + ALP_TO_DIGIT_GAP;
69 else if (is_bigger_letters)
70 return (a - 'A') + ALP_TO_DIGIT_GAP;
71
72 return PERMSRV_ERROR;
73 }
74
75 #define CHAR_COUNT_PER_BYTE 2
76 #define HALF_BYTE_SIZE 4U
get_byte_value_from_buff(const char * buff,uint32_t len,uint8_t * res)77 static int32_t get_byte_value_from_buff(const char *buff, uint32_t len, uint8_t *res)
78 {
79 bool check = ((buff == NULL) || (len < CHAR_COUNT_PER_BYTE));
80 if (check) {
81 tloge("invalid parameter\n");
82 return PERMSRV_ERROR;
83 }
84
85 int8_t h_val = asc2hex(*buff);
86 int8_t l_val = asc2hex(*(buff + 1));
87 if (((int32_t)h_val == H_L_ERROR_NUM_VAL) || ((int32_t)l_val == H_L_ERROR_NUM_VAL))
88 return PERMSRV_ERROR;
89
90 *res = (uint8_t)(((uint8_t)h_val << HALF_BYTE_SIZE) | (uint8_t)l_val);
91 return 0;
92 }
93
perm_srv_convert_str_to_uuid(const char * buff,uint32_t len,TEE_UUID * uuid)94 static int32_t perm_srv_convert_str_to_uuid(const char *buff, uint32_t len, TEE_UUID *uuid)
95 {
96 const char *p = buff;
97 uint8_t add_pos = 0;
98 uint8_t tmp_val = 0;
99 /* These numbers are marked '-' */
100 uint8_t add_pos_array[POS_ARRAY_SIZE] = { 8, 13, 18, 23, 36 };
101 uint8_t parsed_buffer[BYTE_COUNT_IN_UUID] = { 0 };
102 int32_t i;
103 bool is_invalid = (buff == NULL || uuid == NULL);
104 if (is_invalid)
105 return PERMSRV_ERROR;
106
107 for (i = 0; i < BYTE_COUNT_IN_UUID; i++) {
108 if (get_byte_value_from_buff(p, len - (uint32_t)(p - buff), &tmp_val) != 0)
109 return PERMSRV_ERROR;
110 parsed_buffer[i] = tmp_val;
111 p += CHAR_COUNT_PER_BYTE;
112
113 if (add_pos >= POS_ARRAY_SIZE)
114 break;
115
116 if ((uint8_t)(p - buff) == add_pos_array[add_pos]) {
117 if (*p != '-')
118 break;
119
120 p++;
121 add_pos++;
122 }
123 }
124 /* not touch the end of buff */
125 if (p != (buff + len))
126 return PERMSRV_ERROR;
127
128 add_pos = 0;
129 uuid->timeLow = byte_to_integer(parsed_buffer, BYTE_COUNT_IN_UUID - add_pos, sizeof(uuid->timeLow));
130 add_pos += (uint8_t)sizeof(uuid->timeLow);
131 uuid->timeMid = (uint16_t)byte_to_integer(parsed_buffer + add_pos,
132 BYTE_COUNT_IN_UUID - add_pos, sizeof(uuid->timeMid));
133 add_pos += (uint8_t)sizeof(uuid->timeMid);
134 uuid->timeHiAndVersion = (uint16_t)byte_to_integer(parsed_buffer +
135 add_pos, BYTE_COUNT_IN_UUID - add_pos, sizeof(uuid->timeHiAndVersion));
136 add_pos += (uint8_t)sizeof(uuid->timeHiAndVersion);
137 for (i = 0; i < NODE_LEN; i++)
138 uuid->clockSeqAndNode[i] = parsed_buffer[i + add_pos];
139
140 return 0;
141 }
142
parser_callee_ta_uuid(const uint8_t * buff,uint32_t len,TEE_UUID * uuid)143 static int32_t parser_callee_ta_uuid(const uint8_t *buff, uint32_t len, TEE_UUID *uuid)
144 {
145 int32_t ret;
146
147 if (len <= (sizeof(uint16_t) + UUID_STR_LEN)) {
148 tloge("invalid calleeTA uuid info\n");
149 return PERMSRV_ERROR;
150 }
151
152 uint16_t value_len = (uint16_t)byte_to_integer(buff, len, sizeof(value_len));
153 if (value_len != UUID_STR_LEN) {
154 tloge("invalid calleeTA uuid info\n");
155 return PERMSRV_ERROR;
156 }
157
158 /* can make sure buffer is bigger enough */
159 ret = perm_srv_convert_str_to_uuid((const char *)buff + sizeof(value_len), value_len, uuid);
160 return ret;
161 }
162
163 /*
164 * inner tlv format
165 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++
166 * +----tag----+----len----+-----------value-------------+
167 * + 1 byte + 1 byte + 1 or 2 byte(depend on len) +
168 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++
169 */
parse_inner_tag(const uint8_t * tlv,uint32_t tlv_len,uint8_t * total_len)170 static int32_t parse_inner_tag(const uint8_t *tlv, uint32_t tlv_len, uint8_t *total_len)
171 {
172 bool is_invalid = (tlv == NULL || total_len == NULL || tlv_len < TLV_VALUE_OFFSET);
173 if (is_invalid)
174 return PERMSRV_ERROR;
175
176 if ((int32_t)(*tlv) != V_ASN1_INTEGER)
177 return PERMSRV_ERROR;
178
179 uint8_t len = (uint8_t)(*(tlv + ASN1_TLV_TAG_OFFSET));
180 if (len == ASN1_TLV_TAG_OFFSET) {
181 *total_len = TLV_VALUE_OFFSET;
182 return (int32_t)(*(tlv + TLV_LEN_OFFSET));
183 } else if (len == TLV_LEN_OFFSET && tlv_len > TLV_VALUE_OFFSET) {
184 *total_len = (uint8_t)TLV_LLEN;
185 return (((int32_t)(*(tlv + TLV_VALUE_OFFSET))) +
186 (((int32_t)((*(tlv + TLV_LEN_OFFSET)) << UINT8_TYPE_BITS_LEN))));
187 } else {
188 /* tag value is too big >= 65536 */
189 return PERMSRV_ERROR;
190 }
191 }
192
193 /*
194 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++
195 * +--ASN1 INTEGER--+----len----+--[inner tlv][value]---+
196 * +-----1 byte-----+---2 byte---+------(4+4)-----------+
197 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++
198 */
199 #define COMMAND_ID_INNER_TLV_LEN 4
200 #define COMMAND_ID_INFO_LEN (TLV_VALUE_OFFSET + COMMAND_ID_INNER_TLV_LEN + sizeof(uint32_t))
201
parser_callee_ta_command_id(const uint8_t * buff,uint32_t len,struct callee_ta_info * callee)202 static int32_t parser_callee_ta_command_id(const uint8_t *buff, uint32_t len, struct callee_ta_info *callee)
203 {
204 uint32_t offset = 0;
205 uint32_t index;
206 uint8_t inner_tlv_len;
207 int32_t tag;
208 uint32_t i = 0;
209
210 bool is_invalid = (((len / COMMAND_ID_INFO_LEN) > MAX_CALLEE_COMMAND_COUNT) ||
211 ((len % COMMAND_ID_INFO_LEN) != 0));
212 if (is_invalid) {
213 tloge("invalid command 0x%x\n", len);
214 return PERMSRV_ERROR;
215 }
216
217 uint32_t *command_id = TEE_Malloc((len / COMMAND_ID_INFO_LEN) * sizeof(uint32_t), 0);
218 if (command_id == NULL) {
219 tloge("malloc command_id failed\n");
220 return PERMSRV_ERROR;
221 }
222
223 while (offset < len) {
224 tag = parse_inner_tag(buff + offset + TLV_VALUE_OFFSET, len - offset - TLV_VALUE_OFFSET, &inner_tlv_len);
225 is_invalid = (tag != TLV_TAG_CALLEETA_COMMAND_ID || inner_tlv_len != COMMAND_ID_INNER_TLV_LEN);
226 if (is_invalid) {
227 TEE_Free(command_id);
228 return PERMSRV_ERROR;
229 }
230
231 index = TLV_VALUE_OFFSET + inner_tlv_len;
232 if ((offset + index + sizeof(uint32_t)) > len) {
233 tloge("invalid callee command ID len\n");
234 TEE_Free(command_id);
235 return PERMSRV_ERROR;
236 }
237 *(command_id + i) = byte_to_integer((buff + offset + index),
238 len - offset - index, sizeof(offset));
239
240 offset += (uint32_t)COMMAND_ID_INFO_LEN;
241 i++;
242 if (i >= (len / COMMAND_ID_INFO_LEN) * sizeof(uint32_t))
243 break;
244 }
245
246 callee->command_num = (len / (uint32_t)COMMAND_ID_INFO_LEN);
247 callee->command_id = command_id;
248 return PERMSRV_OK;
249 }
250
is_duplicate_callee(const struct config_info * config,const struct callee_ta_info * callee_info)251 static bool is_duplicate_callee(const struct config_info *config, const struct callee_ta_info *callee_info)
252 {
253 struct callee_ta_info *temp = config->control_info.callee_info;
254 int32_t rc;
255
256 while (temp != NULL) {
257 rc = TEE_MemCompare(&temp->uuid, &callee_info->uuid, sizeof(callee_info->uuid));
258 if (rc == 0)
259 return true;
260
261 temp = temp->next;
262 }
263
264 return false;
265 }
266
parser_fill_callee(const uint8_t * buff,uint32_t len,uint32_t value_len,struct config_info * config)267 static int32_t parser_fill_callee(const uint8_t *buff, uint32_t len, uint32_t value_len, struct config_info *config)
268 {
269 int32_t ret;
270 int32_t tag;
271 uint32_t index;
272 uint8_t inner_tlv_len = 0;
273
274 index = TLV_VALUE_OFFSET;
275 if (len < index)
276 return PERMSRV_ERROR;
277
278 uint32_t command_len = len - index;
279 tag = parse_inner_tag(buff + index, command_len, &inner_tlv_len);
280 bool is_invalid = (tag != TLV_TAG_CALLEETA_UUID ||
281 value_len <= (uint32_t)(inner_tlv_len + sizeof(uint16_t) + UUID_STR_LEN));
282 if (is_invalid) {
283 tloge("invalid tag value for calleeTA\n");
284 return PERMSRV_ERROR;
285 }
286
287 index += inner_tlv_len;
288
289 struct callee_ta_info *callee_info = NULL;
290 callee_info = TEE_Malloc(sizeof(*callee_info), 0);
291 if (callee_info == NULL) {
292 tloge("malloc callee info failed\n");
293 return PERMSRV_ERROR;
294 }
295
296 command_len = value_len - inner_tlv_len;
297 ret = parser_callee_ta_uuid(buff + index, command_len, &callee_info->uuid);
298 is_invalid = (ret != PERMSRV_OK) || (is_duplicate_callee(config, callee_info));
299 if (is_invalid) {
300 tloge("parser callee ta uuid failed\n");
301 TEE_Free(callee_info);
302 return PERMSRV_ERROR;
303 }
304
305 index += (uint32_t)sizeof(uint16_t) + UUID_STR_LEN;
306
307 command_len = value_len - (inner_tlv_len + (uint32_t)sizeof(uint16_t) + UUID_STR_LEN);
308 ret = parser_callee_ta_command_id(buff + index, command_len, callee_info);
309 if (ret != PERMSRV_OK) {
310 tloge("parser callee command id failed\n");
311 TEE_Free(callee_info);
312 return PERMSRV_ERROR;
313 }
314
315 callee_info->next = config->control_info.callee_info;
316 config->control_info.callee_info = callee_info;
317
318 return PERMSRV_OK;
319 }
320
321 #define CALLEE_UUID_INNER_TLV_LEN 3
322 /*
323 * ++++++++++++++++++++++++++++++++ calleeTA info ++++++++++++++++++++++++++++++++++
324 * +--ASN1 tag--+----len----+--[inner tlv] [[value_len][value]] [child elements]---+
325 * +---1 byte---+--2 byte---+--------------------depend on len-----------------------+
326 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
327 *
328 * +++++++++++ [[value_len][value]] [child elements]++++++++++++
329 * +--value_len--+----value----+-------[child elements]---------+
330 * +---2 byte---+----x bytes----+----------x bytes--------------+
331 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
332 */
parser_callee_info(const uint8_t * buff,uint32_t len,struct config_info * config)333 static int32_t parser_callee_info(const uint8_t *buff, uint32_t len, struct config_info *config)
334 {
335 int32_t tag_type;
336 uint32_t value_len;
337 int32_t ret;
338 uint32_t offset = 0;
339 uint32_t i = 0;
340
341 while (offset < len) {
342 bool is_invalid = ((i > MAX_CALLEE_TA_COUNT) ||
343 ((len - offset) < (TLV_VALUE_OFFSET + CALLEE_UUID_INNER_TLV_LEN)));
344 if (is_invalid) {
345 tloge("invalid len for calleeTA info\n");
346 return PERMSRV_ERROR;
347 }
348
349 tag_type = *(buff + offset);
350 if (tag_type != V_ASN1_SEQUENCE)
351 return PERMSRV_ERROR;
352
353 value_len = byte_to_integer(buff + offset + ASN1_TLV_TAG_OFFSET,
354 len - offset - ASN1_TLV_TAG_OFFSET, sizeof(uint16_t));
355 if (value_len > (len - TLV_VALUE_OFFSET)) {
356 tloge("invalid value len for single calleeTA info\n");
357 return PERMSRV_ERROR;
358 }
359
360 ret = parser_fill_callee(buff + offset, len - offset, value_len, config);
361 if (ret != PERMSRV_OK)
362 return PERMSRV_ERROR;
363
364 i++;
365 if ((UINT32_MAX - offset) <= (TLV_VALUE_OFFSET + value_len)) {
366 tloge("invalid tlv data\n");
367 return PERMSRV_ERROR;
368 }
369
370 offset += (TLV_VALUE_OFFSET + value_len);
371 }
372
373 return PERMSRV_OK;
374 }
375
376 /*
377 * ++++++++++++++++++++++++++++++++++++++++++++++++++
378 * +--ASN1 tag--+----len----+--[inner tlv][value]---+
379 * +---1 byte---+--2 byte---+------depend on len----+
380 * ++++++++++++++++++++++++++++++++++++++++++++++++++
381 */
config_tlv_check_node(const uint8_t * buff,uint32_t len,uint32_t * offset,int32_t * tag,uint16_t * value_len)382 static int32_t config_tlv_check_node(const uint8_t *buff, uint32_t len,
383 uint32_t *offset, int32_t *tag, uint16_t *value_len)
384 {
385 uint8_t inner_tlv_len = 0;
386
387 if (len < TLV_VALUE_OFFSET) {
388 tloge("invalid buff len\n");
389 return PERMSRV_ERROR;
390 }
391
392 *tag = parse_inner_tag(buff + TLV_VALUE_OFFSET, len - TLV_VALUE_OFFSET, &inner_tlv_len);
393 if (*tag < 0) {
394 tloge("invalid tag value\n");
395 return PERMSRV_ERROR;
396 }
397
398 *offset = TLV_VALUE_OFFSET + (uint32_t)inner_tlv_len;
399
400 uint16_t tlv_value_len = (uint16_t)byte_to_integer(buff + ASN1_TLV_TAG_OFFSET,
401 len - ASN1_TLV_TAG_OFFSET, sizeof(tlv_value_len));
402 if (tlv_value_len <= inner_tlv_len) {
403 tloge("tlv value len 0x%x\n", tlv_value_len);
404 return PERMSRV_ERROR;
405 }
406
407 *value_len = tlv_value_len - (uint16_t)inner_tlv_len;
408 if ((uint32_t)(*value_len) >= len) {
409 tloge("invalid value len\n");
410 return PERMSRV_ERROR;
411 }
412
413 if ((len - (uint32_t)(*value_len)) < (uint32_t)(*offset)) {
414 tloge("invalid value len\n");
415 return PERMSRV_ERROR;
416 }
417
418 return PERMSRV_OK;
419 }
420
get_tag_uuid(const uint8_t * buff,uint32_t len,struct config_info * config)421 static int32_t get_tag_uuid(const uint8_t *buff, uint32_t len, struct config_info *config)
422 {
423 int32_t ret;
424
425 if (len != UUID_STR_LEN) {
426 tloge("config tlv parser invalid uuid\n");
427 return PERMSRV_ERROR;
428 }
429
430 /* make sure buffer is big enough */
431 ret = perm_srv_convert_str_to_uuid((const char *)buff, len, &(config->uuid));
432 if (ret != PERMSRV_OK) {
433 tloge("invalid uuid\n");
434 return PERMSRV_ERROR;
435 }
436
437 return PERMSRV_OK;
438 }
439
config_tlv_parser_basic_info(const uint8_t * buff,uint32_t len,struct config_info * config)440 static int32_t config_tlv_parser_basic_info(const uint8_t *buff, uint32_t len, struct config_info *config)
441 {
442 int32_t ret;
443 int32_t tag = 0;
444 uint16_t value_len = 0;
445 uint32_t offset = 0;
446 uint32_t child_offset = 0;
447
448 while (offset < len) {
449 ret = config_tlv_check_node(buff + offset, len - offset, &child_offset, &tag, &value_len);
450 if (ret != PERMSRV_OK) {
451 tloge("invalid tlv data\n");
452 return PERMSRV_ERROR;
453 }
454
455 switch (tag) {
456 case TLV_TAG_UUID:
457 ret = get_tag_uuid(buff + offset + child_offset, value_len, config);
458 break;
459 case TLV_TAG_SERVICE_NAME:
460 ret = memcpy_s(config->service_name, MAX_SERVICE_NAME_LEN, buff + offset + child_offset, value_len);
461 if (ret != EOK)
462 return PERMSRV_ERROR;
463 config->service_name_len = value_len;
464 break;
465 default:
466 break;
467 }
468 bool is_invalid = (((UINT32_MAX - offset) <= (child_offset + value_len)) || (ret != PERMSRV_OK));
469 if (is_invalid) {
470 tloge("invalid tlv data\n");
471 config->service_name_len = 0;
472 return PERMSRV_ERROR;
473 }
474
475 offset += child_offset + value_len;
476 }
477 return PERMSRV_OK;
478 }
479
config_tlv_value_to_manifest_info(const uint8_t * buff,uint32_t len,int32_t tag,struct config_info * config)480 static void config_tlv_value_to_manifest_info(const uint8_t *buff, uint32_t len, int32_t tag,
481 struct config_info *config)
482 {
483 switch (tag) {
484 case TLV_TAG_SINGLE_INSTANCE:
485 config->manifest_info.single_instance = (bool)(*buff);
486 break;
487 case TLV_TAG_MULTI_SESSION:
488 config->manifest_info.multi_session = (bool)(*buff);
489 break;
490 case TLV_TAG_HEAP_SIZE:
491 config->manifest_info.heap_size = byte_to_integer(buff, len, sizeof(len));
492 break;
493 case TLV_TAG_STACK_SIZE:
494 config->manifest_info.stack_size = byte_to_integer(buff, len, sizeof(len));
495 break;
496 case TLV_TAG_INSTANCE_KEEP_ALIVE:
497 config->manifest_info.instance_keep_alive = (bool)(*buff);
498 break;
499 case TLV_TAG_MEM_PAGE_ALIGN:
500 config->manifest_info.mem_page_align = (bool)(*buff);
501 break;
502 case TLV_TAG_TARGET_TYPE:
503 config->manifest_info.target_type = byte_to_integer(buff, len, sizeof(len));
504 break;
505 default:
506 break;
507 }
508 }
509
config_tlv_parser_manifest_info(const uint8_t * buff,uint32_t len,struct config_info * config)510 static int32_t config_tlv_parser_manifest_info(const uint8_t *buff, uint32_t len, struct config_info *config)
511 {
512 int32_t tag = 0;
513 uint32_t offset = 0;
514 uint16_t value_len = 0;
515 uint32_t child_offset = 0;
516 int32_t ret;
517
518 while (offset < len) {
519 ret = config_tlv_check_node(buff + offset, len - offset, &child_offset, &tag, &value_len);
520 if (ret != PERMSRV_OK) {
521 tloge("invalid tlv data\n");
522 return PERMSRV_ERROR;
523 }
524 bool is_invalid = ((tag == TLV_TAG_HEAP_SIZE || tag == TLV_TAG_STACK_SIZE) && (value_len != sizeof(uint32_t)));
525 if (is_invalid)
526 return PERMSRV_ERROR;
527
528 config_tlv_value_to_manifest_info(buff + offset + child_offset, value_len, tag, config);
529
530 if ((UINT32_MAX - offset) <= (child_offset + value_len)) {
531 tloge("invalid tlv data\n");
532 return PERMSRV_ERROR;
533 }
534
535 offset += child_offset + value_len;
536 }
537
538 return PERMSRV_OK;
539 }
540
config_tlv_parser_info(const uint8_t * buff,uint32_t len,struct config_info * config)541 static int32_t config_tlv_parser_info(const uint8_t *buff, uint32_t len, struct config_info *config)
542 {
543 uint32_t offset = 0;
544 uint16_t value_len = 0;
545 uint32_t child_offset = 0;
546 int32_t ret;
547 int32_t tag = 0;
548
549 while (offset < len) {
550 ret = config_tlv_check_node(buff + offset, len - offset, &child_offset, &tag, &value_len);
551 if (ret != PERMSRV_OK) {
552 tloge("invalid tlv data\n");
553 return PERMSRV_ERROR;
554 }
555
556 switch (tag) {
557 case TLV_TAG_DEBUG_DEVICE_ID:
558 check_device_id(config, buff + offset + child_offset, value_len);
559 break;
560 default:
561 break;
562 }
563
564 if ((UINT32_MAX - offset) <= (child_offset + value_len)) {
565 tloge("invalid tlv data\n");
566 return PERMSRV_ERROR;
567 }
568
569 offset += child_offset + value_len;
570 }
571
572 return PERMSRV_OK;
573 }
574
575 #define TA_MANAGER_TRUSTONIC 1
576 static const char g_ta_manager_trustonic[] = "Trustonic";
parser_ta_manager(const uint8_t * buff,uint32_t len,struct config_info * config)577 static void parser_ta_manager(const uint8_t *buff, uint32_t len, struct config_info *config)
578 {
579 if (len == (sizeof(g_ta_manager_trustonic) - 1) && TEE_MemCompare(g_ta_manager_trustonic, buff, len) == 0)
580 config->control_info.ta_manager = TA_MANAGER_TRUSTONIC;
581 }
582
config_tlv_parser_control_info(const uint8_t * buff,uint32_t len,struct config_info * config)583 static int32_t config_tlv_parser_control_info(const uint8_t *buff, uint32_t len, struct config_info *config)
584 {
585 uint32_t offset = 0;
586 uint32_t child_offset = 0;
587 int32_t ret;
588 uint16_t value_len = 0;
589 int32_t tag = 0;
590
591 while (offset < len) {
592 ret = config_tlv_check_node(buff + offset, len - offset, &child_offset, &tag, &value_len);
593 if (ret != PERMSRV_OK) {
594 tloge("invalid tlv data\n");
595 return PERMSRV_ERROR;
596 }
597
598 switch (tag) {
599 case TLV_TAG_SE_INFO:
600 case TLV_TAG_DEBUG_INFO:
601 ret = config_tlv_parser_info(buff + offset + child_offset, value_len, config);
602 break;
603 case TLV_TAG_CALLEETA_INFO:
604 ret = parser_callee_info(buff + offset + child_offset, value_len, config);
605 break;
606 case TLV_TAG_TA_MANAGER:
607 parser_ta_manager(buff + offset + child_offset, value_len, config);
608 break;
609 default:
610 break;
611 }
612 bool is_invalid = (ret != PERMSRV_OK || ((UINT32_MAX - offset) <= (child_offset + value_len)));
613 if (is_invalid) {
614 tloge("parser control info failed\n");
615 return PERMSRV_ERROR;
616 }
617
618 offset += child_offset + value_len;
619 }
620
621 return PERMSRV_OK;
622 }
623
config_tlv_parser_child_sequences(const uint8_t * buff,uint32_t len,struct config_info * config)624 static int32_t config_tlv_parser_child_sequences(const uint8_t *buff, uint32_t len, struct config_info *config)
625 {
626 uint32_t offset = 0;
627 uint16_t v_len = 0;
628 int32_t ret;
629 uint32_t child_offset = 0;
630 int32_t tag = 0;
631
632 while (offset < len) {
633 ret = config_tlv_check_node(buff + offset, len - offset, &child_offset, &tag, &v_len);
634 if (ret != PERMSRV_OK) {
635 tloge("invalid tlv data\n");
636 return PERMSRV_ERROR;
637 }
638
639 switch (tag) {
640 case TLV_TAG_TA_BASIC_INFO:
641 ret = config_tlv_parser_basic_info(buff + offset + child_offset, v_len, config);
642 break;
643 case TLV_TAG_TA_MANIFEST_INFO:
644 ret = config_tlv_parser_manifest_info(buff + offset + child_offset, v_len, config);
645 break;
646 case TLV_TAG_TA_CONTROL_INFO:
647 ret = config_tlv_parser_control_info(buff + offset + child_offset, v_len, config);
648 break;
649 default:
650 break;
651 }
652 bool is_invalid = (ret != PERMSRV_OK || ((UINT32_MAX - offset) <= (child_offset + v_len)));
653 if (is_invalid) {
654 tloge("parser control info failed\n");
655 return PERMSRV_ERROR;
656 }
657
658 offset += child_offset + v_len;
659 }
660
661 return PERMSRV_OK;
662 }
663
parser_jar_tlv_to_config(const uint8_t * buff,uint32_t len,struct config_info * config)664 static int32_t parser_jar_tlv_to_config(const uint8_t *buff, uint32_t len, struct config_info *config)
665 {
666 uint32_t offset = 0;
667 int32_t tag = 0;
668 uint16_t value_len = 0;
669 int32_t ret;
670
671 if ((int32_t)(*buff) != V_ASN1_SEQUENCE) {
672 tloge("invalid tag value\n");
673 return PERMSRV_ERROR;
674 }
675
676 ret = config_tlv_check_node(buff, len, &offset, &tag, &value_len);
677 if (ret != PERMSRV_OK) {
678 tloge("invalid tlv data\n");
679 return PERMSRV_ERROR;
680 }
681
682 ret = config_tlv_parser_child_sequences(buff + offset, value_len, config);
683 return ret;
684 }
685
release_callee_info(struct callee_ta_info * info)686 static void release_callee_info(struct callee_ta_info *info)
687 {
688 struct callee_ta_info *temp = info;
689
690 while (temp != NULL) {
691 if (temp->command_id != NULL) {
692 TEE_Free(temp->command_id);
693 temp->command_id = NULL;
694 }
695
696 struct callee_ta_info *p = temp;
697 temp = temp->next;
698 TEE_Free(p);
699 p = NULL;
700 }
701
702 info = NULL;
703 }
704
check_cn_validation(const uint8_t * cn,size_t cn_size,const struct config_info * info)705 static TEE_Result check_cn_validation(const uint8_t *cn, size_t cn_size, const struct config_info *info)
706 {
707 uint8_t buff[TA_CERT_MAX_CN_INFO_LEN] = { 0 };
708 errno_t ret;
709
710 bool param_invalid =
711 (cn_size > TA_CERT_MAX_CN_INFO_LEN ||
712 (info->service_name_len > (TA_CERT_MAX_CN_INFO_LEN - (UUID_STR_LEN + TA_CERT_CN_UNDERLINE_SIZE))));
713
714 if (param_invalid)
715 return TEE_ERROR_BAD_PARAMETERS;
716
717 if (cn_size != (info->service_name_len + UUID_STR_LEN + TA_CERT_CN_UNDERLINE_SIZE)) {
718 tloge("invalid cn size: 0x%x\n", cn_size);
719 return TEE_ERROR_GENERIC;
720 }
721
722 if (perm_srv_convert_uuid_to_str(&(info->uuid), (char *)buff, sizeof(buff)) != TEE_SUCCESS)
723 return TEE_ERROR_GENERIC;
724
725 buff[UUID_STR_LEN] = '_';
726 ret = memcpy_s(&buff[UUID_STR_LEN + TA_CERT_CN_UNDERLINE_SIZE],
727 sizeof(buff) - UUID_STR_LEN - TA_CERT_CN_UNDERLINE_SIZE, info->service_name, info->service_name_len);
728 if (ret != EOK)
729 return TEE_ERROR_GENERIC;
730
731 if (TEE_MemCompare(buff, cn, cn_size) != 0) {
732 tloge("uuid or service name mismatch in TA cert and configs\n");
733 return TEE_ERROR_GENERIC;
734 }
735
736 return TEE_SUCCESS;
737 }
738
ta_clear_list(const struct dlist_node * task_config_list)739 static void ta_clear_list(const struct dlist_node *task_config_list)
740 {
741 struct dlist_node *pos = NULL;
742 struct dlist_node *tmp = NULL;
743 struct task_config *task_entry = NULL;
744
745 dlist_for_each_safe(pos, tmp, task_config_list) {
746 task_entry = dlist_entry(pos, struct task_config, head);
747 dlist_delete(&task_entry->head);
748 TEE_Free(task_entry);
749 task_entry = NULL;
750 }
751 }
752
check_contain_dynconf(const struct perm_config * perm_config)753 static uint32_t check_contain_dynconf(const struct perm_config *perm_config)
754 {
755 const char *dynconf_tag = DYN_CONFING_TAG;
756 for (uint32_t i = 0; i < perm_config->tlv_len - strlen(dynconf_tag); i++) {
757 for (uint32_t j = 0; j < strlen(dynconf_tag); j++) {
758 if (*(perm_config->tlv_buf + i + j) != *(dynconf_tag + j))
759 break;
760 if (j == strlen(dynconf_tag) - 1)
761 return perm_config->tlv_len - i;
762 }
763 }
764
765 return 0;
766 }
767
parse_dyntlv_buf(const TEE_UUID * uuid,const struct perm_config * perm_config,const struct config_info * config,uint32_t dynconf_len)768 static TEE_Result parse_dyntlv_buf(const TEE_UUID *uuid, const struct perm_config *perm_config,
769 const struct config_info *config, uint32_t dynconf_len)
770 {
771 if (dynconf_len != 0) {
772 if (TEE_MemCompare(uuid, &(config->uuid), sizeof(*uuid)) == 0) {
773 dynconf_len += 1;
774 TEE_Result res = tee_secure_img_parse_manifest_v3(perm_config->tlv_buf + perm_config->tlv_len,
775 &dynconf_len, false, config->manifest_info.target_type);
776 if (res != TEE_SUCCESS)
777 return TEE_ERROR_GENERIC;
778 } else {
779 tloge("different uuid from config and manifest_info\n");
780 return TEE_ERROR_GENERIC;
781 }
782 }
783 return TEE_SUCCESS;
784 }
785
parser_python_tlv_to_ta_config(const uint8_t * buff,uint32_t len,struct config_info * config)786 static int32_t parser_python_tlv_to_ta_config(const uint8_t *buff, uint32_t len, struct config_info *config)
787 {
788 struct dyn_conf_t dyn_conf;
789 dyn_conf.dyn_conf_buffer = (char *)(uintptr_t)buff;
790 dyn_conf.dyn_conf_size = len;
791 return register_conf(&dyn_conf, install_ta_config, config, sizeof(*config));
792 }
793
parse_tlv_to_ta_config(const struct perm_config * perm_config,struct config_info * config)794 static int32_t parse_tlv_to_ta_config(const struct perm_config *perm_config, struct config_info *config)
795 {
796 int32_t ret;
797 if ((perm_config->policy_version & XML2TLV_PARSE_BIT_MAP) == XML2TLV_JAR_VALUE)
798 ret = parser_jar_tlv_to_config(perm_config->tlv_buf, perm_config->tlv_len, config);
799 else if ((perm_config->policy_version & XML2TLV_PARSE_BIT_MAP) == XML2TLV_PY_VALUE)
800 ret = parser_python_tlv_to_ta_config(perm_config->tlv_buf, perm_config->tlv_len, config);
801 else
802 ret = (int32_t)TEE_ERROR_BAD_PARAMETERS;
803 if (ret != PERMSRV_OK)
804 tloge("parse failed for tlv type:%u, 0-jar, 2-python\n", perm_config->policy_version & XML2TLV_PARSE_BIT_MAP);
805 return ret;
806 }
807
parse_config_body_check(const TEE_UUID * uuid,const struct perm_config * perm_config)808 static bool parse_config_body_check(const TEE_UUID *uuid, const struct perm_config *perm_config)
809 {
810 bool param_invalid = (uuid == NULL || perm_config == NULL || perm_config->tlv_buf == NULL ||
811 perm_config->tlv_len == 0 || perm_config->policy_version == 0 || perm_config->cn_size == 0 ||
812 perm_config->tlv_len > TLV_MAX_LEN || perm_config->tlv_len < strlen(DYN_CONFING_TAG));
813
814 return param_invalid;
815 }
816
get_config_entry(const TEE_UUID * uuid)817 static struct config_info *get_config_entry(const TEE_UUID *uuid)
818 {
819 struct config_info *entry = NULL;
820 struct dlist_node *pos = NULL;
821
822 dlist_for_each_prev(pos, &g_config_list) {
823 entry = dlist_entry(pos, struct config_info, head);
824 if (TEE_MemCompare(uuid, &(entry->uuid), sizeof(entry->uuid)) == 0)
825 return entry;
826 }
827
828 tlogd("cannot find entry uuid\n");
829 return NULL;
830 }
831
perm_srv_update_config_by_same_uuid(struct config_info * new_config)832 static TEE_Result perm_srv_update_config_by_same_uuid(struct config_info *new_config)
833 {
834 struct config_info *old_config = NULL;
835
836 if (pthread_mutex_lock(&g_config_list_lock) != 0) {
837 tloge("Failed to get config list lock\n");
838 return TEE_ERROR_BAD_STATE;
839 }
840
841 old_config = get_config_entry(&new_config->uuid);
842 /*
843 * remove previous one with same uuid if it exists, and retain old task_list
844 * then insert the new one to list
845 */
846 if (old_config != NULL) {
847 dlist_delete(&old_config->head);
848 release_callee_info(old_config->control_info.callee_info);
849 dlist_replace(&old_config->task_config_list, &new_config->task_config_list);
850 TEE_Free(old_config);
851 } else {
852 dlist_init(&new_config->task_config_list);
853 }
854
855 dlist_insert_tail(&new_config->head, &g_config_list);
856
857 (void)pthread_mutex_unlock(&g_config_list_lock);
858 return TEE_SUCCESS;
859 }
860
perm_srv_parse_config_body(const TEE_UUID * uuid,struct perm_config * perm_config)861 TEE_Result perm_srv_parse_config_body(const TEE_UUID *uuid, struct perm_config *perm_config)
862 {
863 struct config_info *config = NULL;
864 TEE_Result ret;
865 int32_t res;
866
867 if (parse_config_body_check(uuid, perm_config)) {
868 tloge("parse_config_body_check fail\n");
869 return TEE_ERROR_BAD_PARAMETERS;
870 }
871
872 uint32_t dynconf_len = check_contain_dynconf(perm_config);
873 perm_config->tlv_len = perm_config->tlv_len - dynconf_len;
874
875 config = TEE_Malloc(sizeof(*config), 0);
876 if (config == NULL)
877 return TEE_ERROR_OUT_OF_MEMORY;
878
879 res = parse_tlv_to_ta_config(perm_config, config);
880 if (res != PERMSRV_OK) {
881 ret = TEE_ERROR_GENERIC;
882 goto error;
883 }
884
885 if (perm_config->cert_type == TA_RELEASE_CERT) {
886 ret = check_cn_validation(perm_config->cn, perm_config->cn_size, config);
887 if (ret != TEE_SUCCESS)
888 goto error;
889 config->control_info.debug_info.valid_device = true;
890 }
891
892 config->version = perm_config->policy_version;
893
894 ret = parse_dyntlv_buf(uuid, perm_config, config, dynconf_len);
895 if (ret != TEE_SUCCESS)
896 goto error;
897
898 ret = perm_srv_update_config_by_same_uuid(config);
899 if (ret != TEE_SUCCESS)
900 goto error;
901
902 return TEE_SUCCESS;
903 error:
904 release_callee_info(config->control_info.callee_info);
905 TEE_Free(config);
906 return ret;
907 }
908
perm_srv_convert_uuid_to_str(const TEE_UUID * uuid,char * buff,uint32_t len)909 TEE_Result perm_srv_convert_uuid_to_str(const TEE_UUID *uuid, char *buff, uint32_t len)
910 {
911 bool check = ((uuid == NULL) || (len < UUID_FORMAT_STRLEN) || (buff == NULL));
912 if (check) {
913 tloge("invalid parameter\n");
914 return TEE_ERROR_GENERIC;
915 }
916
917 int ret = snprintf_s(buff, len, len - 1, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
918 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, uuid->clockSeqAndNode[0],
919 uuid->clockSeqAndNode[1], uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
920 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5], uuid->clockSeqAndNode[6],
921 uuid->clockSeqAndNode[7]); /* refer uuid format definitions */
922 if (ret <= 0) {
923 tloge("convert uuid to string failed %d\n", ret);
924 return TEE_ERROR_GENERIC;
925 }
926
927 return TEE_SUCCESS;
928 }
929
perm_srv_get_config_by_uuid(const TEE_UUID * uuid,struct config_info * config)930 TEE_Result perm_srv_get_config_by_uuid(const TEE_UUID *uuid, struct config_info *config)
931 {
932 struct config_info *entry = NULL;
933 struct dlist_node *pos = NULL;
934
935 bool is_invalid = (uuid == NULL || config == NULL);
936 if (is_invalid) {
937 tloge("get config by uuid bad parameter\n");
938 return TEE_ERROR_BAD_PARAMETERS;
939 }
940
941 if (pthread_mutex_lock(&g_config_list_lock) != 0) {
942 tloge("Failed to get config list lock\n");
943 return TEE_ERROR_BAD_STATE;
944 }
945
946 dlist_for_each(pos, &g_config_list) {
947 entry = dlist_entry(pos, struct config_info, head);
948 if (TEE_MemCompare(uuid, &(entry->uuid), sizeof(*uuid)) == 0) {
949 if (memcpy_s(config, sizeof(*config), entry, sizeof(*entry)) != EOK) {
950 tloge("memcpy operation failed for config info\n");
951 (void)pthread_mutex_unlock(&g_config_list_lock);
952 return TEE_ERROR_GENERIC;
953 }
954 (void)pthread_mutex_unlock(&g_config_list_lock);
955 return TEE_SUCCESS;
956 }
957 }
958
959 (void)pthread_mutex_unlock(&g_config_list_lock);
960 tlogd("cannot find target uuid\n");
961 return TEE_ERROR_GENERIC;
962 }
963
perm_srv_get_config_by_taskid(uint32_t taskid,struct config_info * config)964 TEE_Result perm_srv_get_config_by_taskid(uint32_t taskid, struct config_info *config)
965 {
966 TEE_Result ret = TEE_ERROR_GENERIC;
967 struct config_info *config_entry = NULL;
968 struct task_config *task_entry = NULL;
969 struct dlist_node *config_pos = NULL;
970 struct dlist_node *task_pos = NULL;
971
972 if (config == NULL) {
973 tloge("get config by taskid bad parameter\n");
974 return TEE_ERROR_BAD_PARAMETERS;
975 }
976
977 if (pthread_mutex_lock(&g_config_list_lock) != 0) {
978 tloge("Failed to get config list lock\n");
979 return TEE_ERROR_BAD_STATE;
980 }
981
982 dlist_for_each(config_pos, &g_config_list) {
983 config_entry = dlist_entry(config_pos, struct config_info, head);
984 dlist_for_each(task_pos, &config_entry->task_config_list) {
985 task_entry = dlist_entry(task_pos, struct task_config, head);
986 if (taskid != task_entry->taskid)
987 continue;
988 if (memcpy_s(config, sizeof(*config), config_entry, sizeof(*config_entry)) != EOK) {
989 tloge("memcpy operation failed for config info\n");
990 ret = TEE_ERROR_GENERIC;
991 } else {
992 ret = TEE_SUCCESS;
993 }
994 (void)pthread_mutex_unlock(&g_config_list_lock);
995 return ret;
996 }
997 }
998
999 (void)pthread_mutex_unlock(&g_config_list_lock);
1000 tlogd("cannot find target taskid\n");
1001 return ret;
1002 }
1003
get_register_config_entry(struct config_info ** entry,const TEE_UUID * tmp_uuid,bool * new_config_entry)1004 static TEE_Result get_register_config_entry(struct config_info **entry, const TEE_UUID *tmp_uuid,
1005 bool *new_config_entry)
1006 {
1007 tlogd("register ta not find ta\n");
1008 *entry = get_config_entry(tmp_uuid);
1009 if (*entry == NULL) {
1010 *entry = TEE_Malloc(sizeof(**entry), 0);
1011 if (*entry == NULL) {
1012 tloge("register ta malloc memory failed for config\n");
1013 return TEE_ERROR_OUT_OF_MEMORY;
1014 }
1015 (void)memcpy_s(&(*entry)->uuid, sizeof(TEE_UUID), tmp_uuid, sizeof(TEE_UUID));
1016 (*entry)->version = 0;
1017 dlist_init(&(*entry)->task_config_list);
1018
1019 *new_config_entry = true;
1020 }
1021
1022 return TEE_SUCCESS;
1023 }
1024
ta_add_list(struct config_info * config_entry,struct task_config * tmp_task)1025 static TEE_Result ta_add_list(struct config_info *config_entry, struct task_config *tmp_task)
1026 {
1027 dlist_insert_tail(&tmp_task->head, &config_entry->task_config_list);
1028
1029 return TEE_SUCCESS;
1030 }
1031
perm_srv_register_ta_taskid(const TEE_UUID * uuid,uint32_t taskid,uint32_t userid)1032 TEE_Result perm_srv_register_ta_taskid(const TEE_UUID *uuid, uint32_t taskid, uint32_t userid)
1033 {
1034 struct config_info *config_entry = NULL;
1035 struct task_config *tmp_task = NULL;
1036 bool new_config_entry = false;
1037 TEE_Result ret;
1038
1039 if (uuid == NULL)
1040 return TEE_ERROR_BAD_PARAMETERS;
1041
1042 if (pthread_mutex_lock(&g_config_list_lock) != 0) {
1043 tloge("Failed to get config list lock\n");
1044 return TEE_ERROR_BAD_STATE;
1045 }
1046
1047 ret = get_register_config_entry(&config_entry, uuid, &new_config_entry);
1048 if (ret != TEE_SUCCESS) {
1049 (void)pthread_mutex_unlock(&g_config_list_lock);
1050 return ret;
1051 }
1052
1053 if (new_config_entry)
1054 dlist_insert_tail(&config_entry->head, &g_config_list);
1055
1056 tmp_task = TEE_Malloc(sizeof(*tmp_task), 0);
1057 if (tmp_task == NULL) {
1058 tloge("register ta malloc memory failed for task\n");
1059 ret = TEE_ERROR_OUT_OF_MEMORY;
1060 goto clean_entry;
1061 }
1062
1063 tmp_task->taskid = taskid;
1064 tmp_task->userid = userid;
1065
1066 ret = ta_add_list(config_entry, tmp_task);
1067 if (ret != TEE_SUCCESS)
1068 goto clean_entry;
1069
1070 (void)pthread_mutex_unlock(&g_config_list_lock);
1071 return ret;
1072
1073 clean_entry:
1074 TEE_Free(tmp_task);
1075 (void)pthread_mutex_unlock(&g_config_list_lock);
1076 return ret;
1077 }
1078
perm_srv_unregister_ta_taskid(const TEE_UUID * uuid,uint32_t taskid)1079 TEE_Result perm_srv_unregister_ta_taskid(const TEE_UUID *uuid, uint32_t taskid)
1080 {
1081 struct config_info *config_entry = NULL;
1082 struct task_config *task_entry = NULL;
1083 struct dlist_node *task_pos = NULL;
1084 struct dlist_node *tmp = NULL;
1085
1086 if (uuid == NULL)
1087 return TEE_ERROR_BAD_PARAMETERS;
1088
1089 if (pthread_mutex_lock(&g_config_list_lock) != 0) {
1090 tloge("Failed to get task list lock\n");
1091 return TEE_ERROR_BAD_STATE;
1092 }
1093
1094 config_entry = get_config_entry(uuid);
1095 if (config_entry == NULL) {
1096 tloge("cannot find entry uuid\n");
1097 (void)pthread_mutex_unlock(&g_config_list_lock);
1098 return TEE_ERROR_ITEM_NOT_FOUND;
1099 }
1100
1101 dlist_for_each_safe(task_pos, tmp, &config_entry->task_config_list) {
1102 task_entry = dlist_entry(task_pos, struct task_config, head);
1103 if (task_entry->taskid == taskid) {
1104 dlist_delete(&task_entry->head);
1105 TEE_Free(task_entry);
1106 task_entry = NULL;
1107 (void)pthread_mutex_unlock(&g_config_list_lock);
1108 return TEE_SUCCESS;
1109 }
1110 }
1111
1112 tloge("cannot find entry taskid is 0x%x\n", taskid);
1113 (void)pthread_mutex_unlock(&g_config_list_lock);
1114 return TEE_ERROR_ITEM_NOT_FOUND;
1115 }
1116
perm_srv_clear_ta_permissions(const TEE_UUID * uuid)1117 void perm_srv_clear_ta_permissions(const TEE_UUID *uuid)
1118 {
1119 if (uuid == NULL)
1120 return;
1121
1122 struct dlist_node *pos = NULL;
1123 struct dlist_node *tmp = NULL;
1124 struct config_info *config_entry = NULL;
1125
1126 if (pthread_mutex_lock(&g_config_list_lock) != 0) {
1127 tloge("Failed to get config list lock\n");
1128 return;
1129 }
1130
1131 dlist_for_each_safe(pos, tmp, &g_config_list) {
1132 config_entry = dlist_entry(pos, struct config_info, head);
1133 if (TEE_MemCompare(&config_entry->uuid, uuid, sizeof(*uuid)) == 0) {
1134 dlist_delete(&config_entry->head);
1135 ta_clear_list(&config_entry->task_config_list);
1136 release_callee_info(config_entry->control_info.callee_info);
1137 TEE_Free(config_entry);
1138 config_entry = NULL;
1139 break;
1140 }
1141 }
1142
1143 (void)pthread_mutex_unlock(&g_config_list_lock);
1144 }
1145