• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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